2012年7月4日星期三

timer.asm


.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
includelib user32.lib
includelib kernel32.lib
.data
mebmp db "mebmp",0
szClassName db "correy",0
menocorrey db "meno_correy",0
text db "xxx",0
.data?
hInstance dd ?
hMenu dd ?
stWndClass WNDCLASSEX <>
stMsg MSG <>
.const
me equ 07777h
.code
liuchunli proc hWnd,uMsg,wParam,lParam
   LOCAL ps:PAINTSTRUCT
   LOCAL hdc:HDC
   LOCAL hMemDC:HDC
   LOCAL rect:RECT
   mov eax,uMsg
   .if eax == WM_CREATE
    invoke LoadIcon,hInstance,me
    invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
    invoke SetTimer,hWnd,0,9999,NULL
    ret
   .ELSEIF uMsg==WM_COMMAND
    .elseif eax == WM_CLOSE
      invoke KillTimer,hWnd,0
   .ELSEIF uMsg==WM_TIMER
   invoke MessageBox,0,addr text,addr menocorrey,0
   .elseif uMsg==WM_DESTROY
      invoke PostQuitMessage,NULL
      ret
   .else
    invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    ret
   .endif
   xor eax,eax
   ret
liuchunli endp
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke LoadMenu, 0, OFFSET menocorrey
mov hMenu,eax
push hInstance
pop stWndClass.hInstance
mov stWndClass.cbSize,sizeof WNDCLASSEX
mov stWndClass.hbrBackground,6
invoke LoadCursor,0,IDC_ARROW
mov stWndClass.hCursor,eax
mov stWndClass.lpszClassName,offset szClassName
mov stWndClass.lpfnWndProc,offset liuchunli
invoke RegisterClassEx,addr stWndClass
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szClassName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,hMenu,hInstance,0
mov hInstance,eax
invoke ShowWindow,hInstance,0
invoke UpdateWindow,hInstance
.while TRUE
invoke GetMessage,addr stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr stMsg
invoke DispatchMessage,addr stMsg
.endw
invoke ExitProcess,NULL
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;第二种办法,更简单,没有窗口,因为消息是和线程有关的。
.386
.model stdcall,flat
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib

.code
msg MSG <>
TimerProc proc
  invoke MessageBox,0,0,0,0
  ret
TimerProc endp

start:invoke SetTimer,0,0,3000,addr TimerProc
again:invoke GetMessage,addr msg,0,0,0
  cmp eax,0
  je exit
  invoke DispatchMessage,addr msg
jmp again
exit:invoke ExitProcess,NULL
end start
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//方法三:内核对象等待定时器和异步过程调用(APC)
#include <windows.h>

int main()
{
  LARGE_INTEGER liDueTime;
  liDueTime.QuadPart = -10*10000000LL;

  HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
  SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0);

  WaitForSingleObject(hTimer, INFINITE);//在这里会等待几分钟。感觉其作用和sleep差不多。

  //在这里运行自己的代码。
  MessageBox(0,0,0,0);

  return 0;
}
 /////////////////////////////////////////
#include <windows.h>

VOID CALLBACK TimerAPCProc( LPVOID lpArg, DWORD dwTimerLowValue, DWORD dwTimerHighValue ) 
  //本来是若干时间运行一次,可是:
  //运行的次数至少为循环的次数,至多可能为需要的运行时间除以时间间隔。这个是在调试的时候出现的。
  //用微软的传递参数控制的办法是个不错的选择。
  printf("0k\n");
}

int main( void ) 
{
  HANDLE hTimer = CreateWaitableTimer( NULL,FALSE, TEXT("MyTimer")); 

  LARGE_INTEGER   liDueTime;
  liDueTime.QuadPart = -1 * 10000000;//从几秒后开始运行

  SetWaitableTimer( hTimer, &liDueTime, 1000 /*时间间隔*/ ,  TimerAPCProc, 0, FALSE ); //没有传递数据参数。

  for(int x=0;x<3;x++)//要运行多次,请加循环。
  {
    SleepEx( INFINITE, TRUE ); //可能改变了内核的状态。不可以用Sleep代替。
  }

  CloseHandle( hTimer );

  return 0;
}
//made at 2011.12.26
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//方法四:TLS 线程池
//timeSetEvent已经过时,这个也不说了。
#include <windows.h>

HANDLE gDoneEvent;

VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
  printf("Timer routine called. Parameter is %d.\n",  *(int*)lpParam);
  if(TimerOrWaitFired)   printf("The wait timed out.\n");
  else   printf("The wait event was signaled.\n");

  SetEvent(gDoneEvent);//这个很重要,不然会一直等待。   
}

int main()
{
  gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  HANDLE hTimerQueue = CreateTimerQueue();

  HANDLE hTimer = NULL;
  int arg = 123;
  CreateTimerQueueTimer( &hTimer, hTimerQueue, (WAITORTIMERCALLBACK)TimerRoutine, &arg , 1000, 0, 0);

  //如果上面的倒数第三个参数不为零,在这里可以设置一些代码。
  //设置为非零值也相当与定时器了。
  MessageBox(0,0,0,0);
  //此处的代码也可以实现同步的功能。

  WaitForSingleObject(gDoneEvent, INFINITE);

  CloseHandle(gDoneEvent);
  DeleteTimerQueue(hTimerQueue);
  return 0;
}
//made at 2011.12.26

没有评论:

发表评论