| 
				
				
				
				
				
				
					管理员   | 
				楼主#更多
				
								发布于:2011-12-14 00:23 
								
									 
				
					
				
				 
					|  |  |  |  |  | 大家都知道,函数SetForegroundWindow用于切换前台窗口,但事实上它往往并未达到我们想要的目的:SetForegroundWindow并不能用于和其他进程的窗口协同工作,通常
 情况下SetForegroundWindow会调用FlashWindowEx来闪烁目标窗口,代表已经切换了
 窗口,但事实上往往我们需要在某个时候将我们的窗口弹出到最前台来!曾听说过有高
 手使用修改窗口切换的糸统规则来达到此目的,这样做未必太麻烦了,必定不是每个人
 都是高手呢!下面给大家介绍一个"偏方",非常简单,只是利用了一个MSDN未公开的函数罢了.
 好,come on ,follow me!
 
 这个未公开的函数是:SwitchToThisWindow
 它的c格式的原形是:
 void WINAPI SwitchToThisWindow (
 HWND hWnd,   // Handle to the window that should be activated
 BOOL bRestore // FAULS表示最小化显示;
 );
 
 由于没有原型和库,我们在使用时通常用动态联接法:
 szUser32 db "user32.dll",0
 szFuName db "SwitchToThisWindow",0
 ...
 
 invoke   GetModuleHandle,addr szUser32 ;得到地址空间内user32.dll的模块句柄;
 mov    hUser32,eax
 
 invoke   GetProcaddress,hUser32,addr szFuName ;得到SwitchToThisWindow的地址;
 mov  FuAddr,eax
 
 当想把窗口弹到最前台来时可以用如下语句:
 
 push  TRUE
 push  hWnd  ;窗口句柄
 call  FuAddr
 
 下面是我写的一个例子程序,此程序会每隔五秒钟就弹到最前台来.此程序只在winxp下通过测试,
 如在其他糸统下有问题的话请通知我!
 
 .386
 .model flat,stdcall
 option casemap:none
 include windows.inc
 include gdi32.inc
 includelib gdi32.lib
 include user32.inc
 includelib user32.lib
 include kernel32.inc
 includelib kernel32.lib
 
 .data?
 FuAddr      dd    ?
 hUser32     dd    ?
 hInstance dd ?
 hWinMain    dd ?
 
 .const
 szClassName    db 'MyClass',0
 szCaptionMain db '前台窗口',0
 szText    db '前台窗口切换演示',0
 szUser32       db "user32.DLL",0
 szFuName       db   "SwitchToThisWindow",0
 
 .code
 _ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
 local @stPs:PAINTSTRUCT
 local @stRect:RECT
 local @hDc
 
 mov eax,uMsg
 
 .if eax == WM_PAINT
 invoke BeginPaint,hWnd,addr @stPs
 mov @hDc,eax
 invoke GetClientRect,hWnd,addr @stRect
 invoke DrawText,@hDc,addr szText,-1,addr @stRect,\
 DT_SINGLELINE or DT_CENTER or DT_VCENTER
 invoke EndPaint,hWnd,addr @stPs
 .elseif eax == WM_CLOSE
 invoke DestroyWindow,hWinMain
 invoke PostQuitMessage,NULL
 .elseif eax == WM_TIMER   ;注意此处调用SwitchToThisWindow!
 push  TRUE
 push  hWnd
 call  FuAddr
 .else
 invoke DefWindowProc,hWnd,uMsg,wParam,lParam
 ret
 .endif
 xor eax,eax
 ret
 _ProcWinMain endp
 
 _WinMain proc
 local @stWndClass:WNDCLASSEX
 local @stMsg:MSG
 invoke GetModuleHandle,NULL
 mov hInstance,eax
 invoke   GetModuleHandle,addr szUser32    ;得到地址空间内user32.dll的模块句柄;
 mov   hUser32,eax
 invoke   GetProcAddress,hUser32,addr szFuName   ;得到SwitchToThisWindow的地址;
 mov   FuAddr,eax
 invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
 invoke LoadCursor,0,IDC_ARROW
 mov @stWndClass.hCursor,eax
 push hInstance
 pop @stWndClass.hInstance
 mov @stWndClass.cbSize,sizeof WNDCLASSEX
 mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
 mov @stWndClass.lpfnWndProc,offset _ProcWinMain
 mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
 mov @stWndClass.lpszClassName,offset szClassName
 invoke RegisterClassEx,addr @stWndClass
 
 invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
 WS_OVERLAPPEDWINDOW,150,150,600,400,NULL,NULL,hInstance,NULL
 mov hWinMain,eax
 invoke ShowWindow,hWinMain,SW_SHOWNORMAL
 invoke UpdateWindow,hWinMain
 invoke  SetTimer,hWinMain,1,5000,NULL       ;设置一个计时器,每五秒钟调用一次
 
 .while TRUE
 invoke GetMessage,addr @stMsg,NULL,0,0
 .break .if eax == 0
 invoke TranslateMessage,addr @stMsg
 invoke DispatchMessage,addr @stMsg
 .endw
 ret
 _WinMain endp
 
 start:
 call _WinMain
 invoke ExitProcess,NULL
 end start
 
 
 |  |  |  |  |  | 
 |