MFC的窗口句柄
1.窗口、控件的指针和句柄的相互转化
1)指针转化为句柄在MFC应用程序中首先要获得窗口的指针,然后将其转化为句柄 CWnd* pWnd; HANDLE hWnd = pWnd->GetSafeHwnd();
2)句柄转化为指针在MFC应用程序中首先获得对话框控件的句柄,然后获得其指针HANDLE hWnd;GetDlgItem(IDC_xxx,&hWnd);CWnd * pWnd = FromHandle(hWnd);
获得程序窗口指针的办法:
a.获得主框架窗口指针(任何时候都可以用,只要是MFC程序中):
CWnd* pWnd = AfxGetMainWnd();
b.获得对话框中控件指针:
CWnd* pWnd = GetDlgItem(IDC_xxx);
c.获得对话框中某控件的句柄:
HANDLE GetDlgItem(m_hDLG,m_nID_DlgItem);
d.获得GDI对象的句柄:
HANDLE m_hGDIObj = m_pGDIObj->GetSafeHanle();
2. 如何获取应用程序的实例句柄?
AfxGetInstanceHandle()应用程序的 实例句柄保存在CWinAppIm_hInstance 中,可以这么调用 AfxGetInstancdHandle获得句柄;
Example: HANDLE hInstance=AfxGetInstanceHandle();
3. 如何通过代码获得应用程序主窗口的指针?
AfxGetMainWnd GetSafeHwnd() AfxGetAppName() AfxGetThread
主窗口的 指针保存在CWinThread::m_pMainWnd中,调用 AfxGetMainWnd实现。
【例】 AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED); //使程序最大化.
【例】此例的主窗口是对话框,下面的代码是在另外一个CFileTreeCtrl 类(子窗)中相关函数实现在主对话框(主窗)中的几个 静态文本框(子窗)中显示路径:
CWnd* m_pCWnd= AfxGetMainWnd(); //得到主窗口指针,通过主窗指针访问其他子窗资源
//方法一
m_pCWnd->SetDlgItemText(IDC_STATIC_path,"CWnd* "+m_sCurPath); //在主窗中的子窗(ID:IDC_STATIC_path)中显示字符串
m_pCWnd->SetDlgItemText(IDC_STATIC_who,"路径显示由FileTreeCtrl类完成:");
//方法二
m_pCWnd->SendMessage(STN_CLICKED); //向主窗口发送一个消息,显示任务由主窗完成。
//在主窗的.cpp中有:ON_MESSAGE(STN_CLICKED, OnSTATICpath3)相关描述
//有的函数必须通过窗口的 句柄 来访问,我们可以使用下面的方法三
//CWnd::GetSafeHwnd
//Returns the window handle for a window
//HWND GetSafeHwnd( ) const;
HWND m_hWnd_tree =GetSafeHwnd();//【注】此处得到的只是当前窗口(FileTree类)的句柄
HWND m_hWnd = m_pCWnd->GetSafeHwnd();// 这里才是主窗口的句柄(由主窗指针得到主窗的句柄)
//BOOL SetWindowText( HWND hWnd, LPCTSTR lpString )
::SetWindowText(m_hWnd,"ok2222");//修改主窗口标题
::SetDlgItemText(m_hWnd,IDC_STATIC_path2,"HWND: "+m_sCurPath);
【另】AfxGetThread
CWinThread* AfxGetThread( );
Return Value:Pointer to the currently executing thread.
4.如何在程序中获得其他程序的图标?
AfxGetInstanceHandle()
HINSTANCE AfxGetInstanceHandle( );
Return Value
An HINSTANCE to the current instance of the application.
If called from within a DLL linked with the USRDLL version of MFC, an HINSTANCE to the DLL is returned.
Remarks
This function allows you to retrieve the instance handle of the current application.
AfxGetInstanceHandle always returns the HINSTANCE of your executable file (.EXE) unless it is called from within a DLL linked with the USRDLL version of MFC.
In this case, it returns an HINSTANCE to the DLL.
两种方法:
(1) SDK函数 SHGetFileInfo 或使用 ExtractIcon获得图标资源的 handle(句柄),
(2) SDK函数 SHGetFileInfo获得有关文件的 很多信息,如大小图标,属性,类型等.
Example(1): 在程序窗口左上角显示 NotePad图标.
void CSampleView: OnDraw(CDC * pDC)
{
if( :: SHGetFileInfo(_T("c:\\pwin95\\notepad.exe"),0,&stFileInfo,sizeof(stFileInfo),SHGFI_ICON))
{
pDC ->DrawIcon(10,10,stFileInfo.hIcon);
}
}
Example(2):同样功能,Use ExtractIcon Function
void CSampleView:: OnDraw(CDC *pDC)
{
HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0);
if (hIcon &&hIcon!=(HICON)-1)
pDC->DrawIcon(10,10,hIcon);
}
【说明】关于如何得到系统文件的正确路径,象win.ini system32.ini等的路径,各种系统中具体的路径是不一样的。如:获得notepad.exe的路径正规上来说用;
GetWindowsDirectory 函数得到;如果是调用 win95下的画笔,应该用访问注册表的方法获得其路径;要作成一个比较考究的程序,考虑应该全面点.
HINSTANCE AfxGetResourceHandle( );
Return Value:An HINSTANCE handle where the default resources of the application are loaded。
5. 有关取得桌面句柄 GetDesktopWindow()
MSDN中的例子:
// 静态函数CWnd:: GetDesktopWindow 返回桌面窗口的指针。下例说明了MFC
void CFrameWnd::BeginModalState ()
{
//first count all windows that need to be disabled
UINT nCount=0;
HWND hWnd=:: GetWindow (:: GetDesktopWindow (), GW_CHILD);
while (hWnd!=NULL)
{
if (:: IsWindowEnabled (hwnd) &&
CWnd::FromHandlePermanent (hWnd)!=NULL &&
AfxIsDescendant (pParent->m_hWnd, hWnd) &&
:: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0) == 0)
{
++nCount;
}
hWnd=:: GetWindow (hWnd, GW_HWNDNEXT);
}
}
//用户的问题:下面程序取的不是同一程序的句柄,但是GetModuleFileName返回的结果一样请问为什么
HWND ChWnd;//子窗口句柄
HWND hwDesktop=::GetDesktopWindow();//取得桌面句柄
ChWnd=::GetWindow(hwDesktop,GW_CHILD);//取得桌面子句柄
CString csTitle,csClass,csTm,mLookstring;
char szBuffer255];
while(ChWnd!=NULL)//循环取子句柄的同级句柄
{
if(::IsWindowVisible(ChWnd))//判断是否为可显示窗口
{
::GetWindowText(ChWnd,csTitle.GetBuffer(255),254);
::GetClassName(ChWnd,csClass.GetBuffer(255),254);
csTitle.ReleaseBuffer();//标题
csClass.ReleaseBuffer();//类名
csTm.Format("%08X:",ChWnd);
if(csTitle=="")
{
mLookstring=csTm+csClass;
}
else
{
mLookstring=csTm+csTitle;
}
//这里的窗口句柄不是同一个程序吧?(问题所在!)可是为什莫结果一样
HINSTANCE hInstance = (HINSTANCE)::GetWindowLong(ChWnd,DWL_USER);
::GetModuleFileName(hInstance, szBuffer, sizeof(szBuffer));
MessageBox(szBuffer,mLookstring);
}
ChWnd=::GetWindow(ChWnd,GW_HWNDNEXT);
}
回答:
问题在于Win32下GetWindowLong(ChWnd,DWL_USER)总是返回当前程序运行的hInstance,所以你得到文件名总是一个。所以你要用枚举所有"进程的程序名"来获得程序名。
再谈句柄与指针的区别
许多开始学习VC的朋友,最多听说的两个词莫过于指针和句柄了。
但是,确经常搞不清他们之间的区别。
首先,句柄是一个窗口的标志,也就是所有从CWND类继承下来的,多有句柄这个成员。他能做的,也就是唯一代表一个桌面上的窗口罢了。而指针是一个地址,如果它指向了
一个内存中的对象,那么就可以对它进行任意操作了,当然,并不局限于自己的应用程序,你如果能够获得别的应用程序的某个对象的指针,也可以进行操作。
然而,如果要获得指针,首先,必须找到那个窗口的句柄,然后用函数FromHandle就可以得到他的指针了。
问题1:
如何在自定义的消息中发送一个字符串?例如:
SendMessage(MyWnd,WM_USERDEFINED, 0,0)
如何将字符串Buffer写入wParam或lParam?
你可以把字符串的地址传递过去,因为地址正好是32位。如:
char s256];
SendMessage(MyWnd,WM_USERDEFINED, (WPARAM) s,0)
接收方只需要将wParam赋给一个char*就可以了。但此方法只能使用于在一个进程内部传递数据。
问题2:
1).在VC应用程序框架中,如何加入自己做的类,如何定义这个类的对象,我想在鼠标点击某个菜单项的时候才生成这个对象,做得到吗?(这个类的构造函数是带参数的)。
2).消息发送函数:
PostMessage(HWND handle,WM_MYMESSAGE, WPARAM wParam,LPARAM lParam) 中:
第一个参数如何获得?
如果我的消息是在自己的应用程序中生成的,想发给应用程序的窗口让它显示某些数据(用TextOut函数),能做到吗?
(也可以说是这样的问题:用Appwizard生成应用程序框架,在生成的类(如CView)中如何得到窗口的句柄,并放在PostMessage函数中。)
3).wParam,lParam,在消息响应函数中如何用?vc是怎样保证这两个数传到函数中的?问题比较多,谢谢!
回答:
a.这个问题是肯定的。你可以使用ClassWizard定义类,也可以手工输入。如果类定义已经在某个文件中,只要使用Project|Add files将文件加入工程就可以了。
要想定义类的对象,只要在你的菜单项的相应事件中就可以了。如:
{
MyClass myObject("Hello");
myObject.MyMethod();
}
b.在你自己的程序中传递消息当然没有任何问题,只要你知道要调用的窗口类是从CWnd继承来的,你就可以使用GetSafeHwnd函数获得窗口句柄。
不过一般在自己的同一个程序中有时不愿意使用自定义消息,因为太麻烦。你完全可以给要调用的类添加一个成员函数,只要想显示数据,直接调用这个成员函数不就可以了?
何必使用PostMessage呢?
一般只有在程序间调用,才愿意使用自定义消息。这时,你通常可以使用FindWindow获得窗口句柄(QA000251 "如何利用FindWindow()函数查找程序")。
c.对于MFC已经定义了消息处理函数的消息,MFC会自动把wParam和lParam映射为更容易使用的方式。如OnMouseMove( UINT nFlags, CPoint point )。
对于MFC不能自动处理的函数,如你使用ON_MESSAGE定义消息函数,则MFC会把wParam和lParam原原本本的传递给你的函数,不做任何处理。
一个未公开的Win32 API函数:GetTaskmanWindow ()
下例中还用到: GetProcAddress GetParent(hWnd)
HMODULE hUser32 = GetModuleHandle("user32");
download
// getaskmanwnd.cpp (Windows NT/2000)
//
// 利用一个未公开的Win32 API函数:GetTaskmanWindow,
// 对Windows的任务栏进行操作(显示/隐藏)。这个函数返回拥有任务栏按钮的窗口句柄。
//
// This example will show you how you can obtain a handle to the
// Windows Taskbar window.
//
// (c)1999 Ashot Oganesyan K, SmartLine, Inc
// mailto:ashot@aha.ru, http://www.protect-me.com, http://www.codepile.com
#include <windows.h>
#include <stdio.h>
// User32!GetTaskmanWindow (NT specific!)
//
// This function returns a handle to the window that ownes the taskbar buttons
//
// HWND GetTaskmanWindow()
//
typedef HWND (WINAPI *PROCGETTASKMANWND)(void);
PROCGETTASKMANWND GetTaskmanWindow;
void main(int argc, char* argv])
{
if (argc<2)
{
printf("Usage:\n\ngetaskmanwnd.exe S|H\n");
return;
}
HMODULE hUser32 = GetModuleHandle("user32");
if (!hUser32)
return;
GetTaskmanWindow = (PROCGETTASKMANWND)GetProcAddress(hUser32,"GetTaskmanWindow");
if (!GetTaskmanWindow)
return;
HWND hWnd = GetTaskmanWindow();
if (!hWnd)
return;
if (*argv1]=="H" || *argv1]=="h")
ShowWindow(GetParent(hWnd),SW_HIDE);
else
ShowWindow(GetParent(hWnd),SW_SHOW);
}
6.总结:
在使用MFC时,窗口是经常使用的,所以大家在看完今天这篇,接下来勤加练习,成为C++大神指日可待。
改变自己,从现在做起-----------久馆
MFC的窗口句柄的更多相关文章
- (转载博文)MFC 窗口句柄获取
句柄获取方法(获取该窗口的句柄后,即可向该窗口类类发送消息.处理程序):0.获取所在类窗口的句柄: this->m_hwnd 1.主窗口的句柄: 无论在主窗口类内,还是子窗口类内,获取主窗口句柄 ...
- 将Cocos2dX渲染到MFC窗口上
引用:http://www.cnblogs.com/windeer/archive/2012/11/18/2767750.html 引言 现在智能手机已经慢慢进入大众化,移动类应用开始火爆起来,游戏类 ...
- 【转】vc中使用SendMessage正确发送自定义消息的方法--不错
原文网址:http://zhoumf1214.blog.163.com/blog/static/5241940200910265532959/ 最近在用VC2008做开发,后来由于要用到消息的发送,而 ...
- socket,实现服务器和客户端对话
服务器: #define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string>#include<WinSock ...
- MFC通过对话框窗口句柄获得对话框对象指针
C***Dialog* pWnd= (C***Dialog*)FromHandle(hWnd); //由句柄得到对话框的对象指针 pWnd->xxx( ); ...
- 【转】MFC窗口句柄各类指针获取函数
原文网址:http://www.pythonschool.com/CPP_JHK/5003.html 获取所在类窗口的句柄 this->m_hwnd; // this是一个指针,指向当前类的实例 ...
- MFC DestroyWindow窗口对象和窗口句柄的销毁
考虑单窗口情况: 假设自己通过new创建了一个窗口对象pWnd,然后pWnd->Create.则销毁窗口的调用次序: 1. 手工调用pWnd->DestroyWindow(): 2. De ...
- MFC注册窗口类以及FindWindow按窗口类名查询(避免用#32770获取窗口句柄)
呵呵,最近在研究SendMessage函数,其中需要用到m_hWnd,之后延伸着又尝试获得窗口的句柄,于是遇到了FindWindow函数,原型如下: HWND FindWindow ( LPCSTR ...
- 有关MFC类与其窗口句柄
Attach,其实就是让一个CWnd对象的HWND成员指向这个窗口句柄.这就是Attach主要完成的任务. Detach.如前所述,WNDCLASS其实和CWnd根本没有什么关系.它们之间只是通过CW ...
随机推荐
- nginx优化:配置gzip压缩页面提高访问速度(nginx1.18.0)
一,为什么nginx要使用gzip 1,压缩的作用: 页面使用gzip压缩之后, 页面大小可以压缩到原来的1/7左右, 传输速度和页面打开时间都可以大幅度提高, 有利于用户访问页面体验的提升 2,Ng ...
- java默认值
注意:此处默认值是在类成员时才可以被初始化有默认值 如果时在局部变量中,必须先自己初始化才可以使用,否则编译失败
- D. Rescue Nibel! 解析(思維、組合、離散化、差分)
Codeforce 1420 D. Rescue Nibel! 解析(思維.組合.離散化.差分) 今天我們來看看CF1420D 題目連結 題目 給你\(n\)個區間,求有幾種方法使得\(k\)個區間的 ...
- 撤销rebase与git原理
git对象 git是面向对象的,对象存储在.git/objects文件夹中.此文件夹中,一个对象就是一个文件,文件名就是对象的id 提交commit的时候,每个文件都是一个数据对象,一个树对象会用来维 ...
- 「补课」进行时:设计模式(5)——从 LOL 中学习代理模式
1. 前文汇总 「补课」进行时:设计模式系列 2. 从 LOL 中学习代理模式 我是一个很喜欢玩游戏的人,虽然平时玩游戏的时间并不多,但我也是一个忠实的 LOL 的爱好者,就是段位有点惨不忍睹,常年倔 ...
- SpringBoot中的全局异常处理
SpringBoot中的全局异常处理 本篇要点 介绍SpringBoot默认的异常处理机制. 如何定义错误页面. 如何自定义异常数据. 如何自定义视图解析. 介绍@ControllerAdvice注解 ...
- elk部署(实战一)
项目介绍: 系统:redhat7.6 软件:es+logstash+kibana 6.1 IP+主机名 192.168.0.10 elk1 192.168.0.10 elk2 192.1 ...
- django配置跨域并开发测试接口
1.创建一个测试项目 1.1 创建项目和APP django-admin startproject BookManage # 创建项目 python manage.py startapp books ...
- 【轻松学编程】如何快速学会一门高级编程语言,以python为例
python文章目录 关注公众号"轻松学编程"了解更多. 写在前面:如何快速(比如在一个月内)学会一门高级编程语言? 现在想学一门编程语言并不难,网上有很多资料,包括书籍.博客.视 ...
- GXOI2018 滚粗记
今天考了一次蜜汁省选,滚粗了.想了想,还是写点什么记录一下 8:10 折腾一番总算拿到题目和样例了,一打开dpf,立马感觉到了不对劲. 题目一股浓浓的劣质模拟题的画风,先不说题目质量,单是排版质量都被 ...