Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4604593
  • 博文数量: 671
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 7310
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-14 09:56
文章分类

全部博文(671)

文章存档

2011年(1)

2010年(2)

2009年(24)

2008年(271)

2007年(319)

2006年(54)

我的朋友

分类:

2007-03-17 08:03:35

 
  大家都知道,函数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

  ...

  invokeGetModuleHandle,addr szUser32 ;得到地址空间内user32.dll的模块句柄;

  mov hUser32,eax

  invokeGetProcAddress,hUser32,addr szFuName ;得到SwitchToThisWindow的地址;

  movFuAddr,eax

  当想把窗口弹到最前台来时可以用如下语句:

  pushTRUE

  pushhWnd;窗口句柄

  callFuAddr

  下面是我写的一个例子程序,此程序会每隔五秒钟就弹到最前台来.此程序只在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?

  FuAddrdd?

  hUser32dd?

  hInstance dd ?

  hWinMaindd ?

  .const

  szClassNamedb 'MyClass',0

  szCaptionMain db '前台窗口',0

  szTextdb '前台窗口切换演示',0

  szUser32db "user32.DLL",0

  szFuNamedb"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!

  pushTRUE

  pushhWnd

  callFuAddr

  .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

  invokeGetModuleHandle,addr szUser32;得到地址空间内user32.dll的模块句柄;

  movhUser32,eax

  invokeGetProcAddress,hUser32,addr szFuName;得到SwitchToThisWindow的地址;

  movFuAddr,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

  invokeSetTimer,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
阅读(1522) | 评论(1) | 转发(0) |
0

上一篇:汇编与C配合

下一篇:使用DLL中的资源

给主人留下些什么吧!~~