一颗胡萝卜🌀 哥哥爱槑槑
关注数: 66 粉丝数: 233 发帖数: 11,773 关注贴吧数: 58
delphi如何根据句柄判断窗口的显示状态 有时我们取得一个窗口的句柄,需要知道这个窗口是隐藏还是显示状态?或者我们取得窗体的句柄,想隐藏这个窗体或显示这个窗体,该怎么办呢?这时我们需要用到API函数GetWindowLong或者GetWindowInfo, GetWindowLong的函数原型LONG GetWindowLong( HWND hWnd,int nIndex ) 参数: hWnd:指定窗口的句柄 nIndex:需要获得的信息的类型 值 功能 nIndex取值如下: GWL_EXSTYLE 得到扩展的窗口风格 GWL_STYLE 得到窗口风格 GWL_WNDPROC 得到窗口回调函数的地址,或者句柄。得到后必须使用CallWindowProc函数来调用 GWL_HINSTANCE 得到应用程序运行实例的句柄 GWL_HWNDPARENT 得到父窗口的句柄 GWL_ID 得到窗口的标识符 GWL_USERDATA 得到和窗口相关联的32位的值(每一个窗口都有一个有意留给创建窗口的应用程序是用的32位 的值) 当hWnd标识一个对话框时可以使用下面的值 Value Action DWL_DLGPROC 得到对话框回调函数的地址,或者句柄。得到后必须使用CallWindowProc函数来调用 DWL_MSGRESULT 得到对话框回调函数中消息处理过程的返回值 DWL_USER 得到额外的应用程序私有信息,如一些句柄和指针等 返回值: 成功时,返回一个请求的32位的值 失败时,返回0,可以使用GetLastError来取得错误信息 示例1: long nStyle = ::GetWindowLong(hWnd, GWL_STYLE); // hWnd是一个编辑框的句柄 if(nStyle & ES_PASSWORD) { AfxMessageBox(“这是一个密码域”); } 示例2: LONG GetWindowLong( HWND hWnd, // handle of window int nIndex // offset of value to retrieve ); 第二个参数是0的话,就是指定GW_HWNDFIRST!!! GW_HWNDFIRST = 0; {同级别 Z 序最上} GW_HWNDLAST = 1; {同级别 Z 序最下} GW_HWNDNEXT = 2; {同级别 Z 序之下} GW_HWNDPREV = 3; {同级别 Z 序之上} GW_OWNER = 4; {属主窗口} GW_CHILD = 5; {子窗口中的最上} GetWindowInfo函数原型 BOOL WINAPI GetWindowInfo(__in HWND hwnd,__inout PWINDOWINFO pwi); 参数 hwnd 要检索信息的窗口的句柄。 pwi 指向一个接收信息的 PWINDOWINFO 结构,注意,在调用该函数之前必须设置 cbSize 成员为sizeof(WINDOWINFO)。] typedef struct tagWINDOWINFO { DWORD cbSize; RECT rcWindow; //窗口区域 RECT rcClient; //Client区域 DWORD dwStyle; //窗口样式 DWORD dwExStyle; //窗口扩展样式 DWORD dwWindowStatus; //WS_ACTIVECAPTION表示活动,否则为0 UINT cxWindowBorders; //边框宽度 UINT cyWindowBorders; //边框宽度 ATOM atomWindowType; WORD wCreatorVersion; } WINDOWINFO, *PWINDOWINFO, *LPWINDOWINFO; Members cbSize Type: DWORD The size of the structure, in bytes. The caller must set this member to sizeof(WINDOWINFO). rcWindow Type: RECT The coordinates of the window. rcClient Type: RECT The coordinates of the client area. dwStyle Type: DWORD The window styles. For a table of window styles, see Window Styles. dwExStyle Type: DWORD The extended window styles. For a table of extended window styles, see Extended Window Styles. dwWindowStatus Type: DWORD The window status. If this member is WS_ACTIVECAPTION (0x0001), the window is active. Otherwise, this member is zero. cxWindowBorders Type: UINT The width of the window border, in pixels. cyWindowBorders Type: UINT The height of the window border, in pixels. atomWindowType Type: ATOM The window class atom (see RegisterClass). wCreatorVersion Type: WORD The Windows version of the application that created the window. 返回值 如果函数成功,则返回值为非零值。 如果该函数失败,则返回值为零。要获取扩展的错误的信息,请调用GetLastError . delphi根据句柄判断窗口状态代码 //用GetWindowLong函数 style := GetWindowLong(MyHandle, GWL_STYLE); if (style and WS_VISIBLE) > 0 then //此句柄窗口是显示的 ShowWindow(MyHandle, SW_HIDE) else ShowWindow(MyHandle, SW_SHOW); 或用GetWindowInfo函数 GetWindowInfo(MyHandle, Pwi); if (Pwi.dwStyle and WS_VISIBLE) > 0 then //此句柄窗口是显示的 ShowWindow(MyHandle, SW_HIDE) else ShowWindow(MyHandle, SW_SHOW); 通过这两个函数,我们可以判断窗体的样式来确定窗体的一些我们所需要的信息! 取得窗体信息的函数还有 获取窗口大小(RECT)矩形 以下是使用方法: RECT rct; //创建一个RECT变量,用于接收下面函数的出参。 BOOL GetWindowRect(hwd, &rct); //入参 窗口句柄 //出参 一个RECT变量的地址,于接收函数的获取的值 返回值: 如果成功:返回 非零; 失败:返回零;调用GetLastError()获取错误原因。 获取窗口类名 wchar_t strClassName[30] = {0}; //如果当前程序使用的是unicode字符集,那么就使用wchar_t类型,否则使用char类型。int GetClassName(hwd, strClassName, 30) 入参:hwd,窗口句柄 缓冲区大小 出参:strClassName,缓冲区 返回值: 成功,返回写入到缓冲区的字符个数; 失败,返回 零,调用GetLastError()获取错误原因。 获取DC HDC GetDC(hwd); 入参:hwd,窗口句柄 返回值: 成功,返回,当前窗口的句柄 失败,返回,NULL 获取鼠标位置 POINT pt; GetCursorPos(&pt) 取窗口信息的相关代码 function GetWindowTitle(hwnd: HWND): string; begin SetLength(Result, 255); SetLength(Result, GetWindowText(hwnd, PChar(Result), 255)); end; function GetWindowClass(hwnd: HWND): string; begin SetLength(Result, 255); SetLength(Result, GetClassName(hwnd, PChar(Result), 255)); end; function GetWindowInfo(hwnd: HWND): string; begin Result := GetWindowTitle(hwnd) + ' [' + GetWindowClass(hwnd) + '] (' + IntToStr(hwnd) + ')'; end; function EnumChildProc(hwnd: HWND; lParam: Integer): BOOL; stdcall; var NewNode, ParentNode: TTreeNode; begin Result := True; ParentNode := TTreeNode(lParam); NewNode := ParentNode.Owner.AddChild(ParentNode, GetWindowInfo(hwnd)); EnumChildWindows(hwnd, @EnumChildProc, Integer(NewNode)); end; function EnumWindowsProc(hwnd: HWND; lParam: Integer): BOOL; stdcall; var NewNode: TTreeNode; begin Result := True; NewNode := TTreeView(lParam).Items.Add(nil, GetWindowInfo(hwnd)); EnumChildWindows(hwnd, @EnumChildProc, Integer(NewNode)); end; procedure EnumWindowsTree(Tree: TTreeView); begin EnumWindows(@EnumWindowsProc, Integer(Tree)); end; procedure TForm1.Button1Click(Sender: TObject); begin TreeView1.Items.Clear; EnumWindowsTree(TreeView1); end;
Delphi中window消息截获的实现方式(1) 近来笔者在一个项目中需要实现一个功能:模仿弹出菜单的隐藏方式,即鼠标在窗口的非PanelA区域点击时,使得PanelA隐藏。 经过思考,笔者想到通过处理鼠标的点击事件来实现相应功能。但是,究竟由谁来处理这个点击事件呢?如果窗口中包含多个句柄控件,则不能确定谁能获取到这个鼠标的点击事件,故而无法做出处理。 通过热心网友的帮忙,笔者了解到了window消息截获的实现方式,更棒的是:消息截获并不影响消息的正常处理。最终实现的效果非常完美。在此分享给有需要的朋友。下面是消息截获的实现代码。 1.对于有句柄的控件,可以用一下代码 interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls; type TForm1 = class(TForm) btn1: TButton; btn2: TButton; PageControl1: TPageControl; ts1: TTabSheet; ts2: TTabSheet; procedure FormCreate(Sender: TObject); procedure btn1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure AppMsg(var Msg: TMsg; var Handled: Boolean); end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean); var i:integer; begin case Msg.message of WM_LBUTTONDOWN, WM_LBUTTONDBLCLK: begin //拦截PageControl控件的Tab标签切换事件 if Msg.hwnd=PageControl1.Handle then begin for i:=0 to PageControl1.PageCount-1 do begin if PtInRect(PageControl1.TabRect(i),PageControl1.ScreenToClient(Msg.pt)) then begin Handled:=true; ShowMessage(IntToStr(i)); end; end; end; //拦截Button按钮点击事件 if Msg.hwnd=btn1.Handle then begin Handled:=true; ShowMessage('bbbb'); end; end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Application.OnMessage:=AppMsg; end; procedure TForm1.btn1Click(Sender: TObject); begin ShowMessage('aaaa'); end; end. 2.对于没有句柄的控件,可以通过矩形区域判断 var Pt: TPoint; MyRect: TRect; begin if (Msg.message = WM_LBUTTONUP) or (Msg.message = WM_RBUTTONUP) then begin GetCursorPos(Pt); MyRect.TopLeft.X := OwnButton5.ClientOrigin.x; MyRect.TopLeft.y := OwnButton5.ClientOrigin.y; MyRect.BottomRight.X := MyRect.TopLeft.X +OwnButton5.Width; MyRect.BottomRight.y := MyRect.TopLeft.y +OwnButton5.Height; if not PtInRect(MyRect,Pt) then Panel14.Visible := False; end; end; 需要注意的是:窗口销毁时,如果应用程序需要继续运行,则要在窗口销毁时解除消息截获,即Application.OnMessage:=nil;
1 下一页