【转】有关句柄和指针的常用函数

【转】有关句柄和指针的常用函数
2010年11月11日
  1. 如何获取应用程序的 实例句柄? AfxGetInstanceHandle()[b] 应用程序的 实例句柄保存在CWinAppIm_hInstance 中,可以这么调用 AfxGetInstancdHandle获得句柄.[b] Example: HANDLE hInstance=AfxGetInstanceHandle();
  2. 如何通过代码获得应用程序主窗口的 指针? AfxGetMainWnd GetSafeHwnd() AfxGetAppName() AfxGetThread[b] 主窗口的 指针保存在CWinThread::m_pMainWnd中,调用 AfxGetMainWnd实现。
  【例】 AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED); //使程序最大化.
  【例】此例的主窗口是对话框,下面的代码是在另外一个CFileTreeCtrl 类(子窗)中相关函数实现在主对话框(主窗)中的几个 静态文本框(子窗)中显示路径:[b] CWnd* m_pCWnd= AfxGetMainWnd(); //得到主窗口指针,通过主窗指针访问其他子窗资源[b] //方法一[b] m_pCWnd->SetDlgItemText(IDC_STATIC_path,"CWnd* "+m_sCurPath); //在主窗中的子窗(ID:IDC_STATIC_path)中显示字符串[b] m_pCWnd->SetDlgItemText(IDC_STATIC_who,"路径显示由FileTreeCtrl类完成:");[b] //方法二[b] m_pCWnd->SendMessage(STN_CLICKED); //向主窗口发送一个消息,显示任务由主窗完成。[b] //在主窗的.cpp中有:ON_MESSAGE(STN_CLICKED, OnSTATICpath3)相关描述
  //有的函数必须通过窗口的 句柄 来访问,我们可以使用下面的方法三[b] //CWnd::GetSafeHwnd [b] //Returns the window handle for a window[b] //HWND GetSafeHwnd( ) const;[b] HWND m_hWnd_tree =GetSafeHwnd();//【注】此处得到的只是当前窗口(FileTree类)的句柄[b] HWND m_hWnd = m_pCWnd->GetSafeHwnd();// 这里才是主窗口的句柄(由主窗指针得到主窗的句柄)
  //BOOL SetWindowText( HWND hWnd, LPCTSTR lpString )[b] ::SetWindowText(m_hWnd,"ok2222");//修改主窗口标题[b] ::SetDlgItemText(m_hWnd,IDC_STATIC_path2,"HWND: "+m_sCurPath);
  【另】AfxGetThread[b] CWinThread* AfxGetThread( );[b] Return Value:Pointer to the currently executing thread.
  3. 如何在程序中获得其他程序的 图标? AfxGetInstanceHandle()
  HINSTANCE AfxGetInstanceHandle( );[b] Return Value[b] 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.[b] Remarks[b] 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.
  两种方法:[b] (1) SDK函数 SHGetFileInfo 或使用 ExtractIcon获得图标资源的 handle(句柄),[b] (2) SDK函数 SHGetFileInfo获得有关文件的 很多信息,如大小图标,属性,类型等.
  Example(1): 在程序窗口左上角显示 NotePad图标.[b] void CSampleView: OnDraw(CDC * pDC)[b] {[b] if( :: SHGetFileInfo(_T("c:\\pwin95\\notepad.exe"),0,[b] &stFileInfo,sizeof(stFileInfo),SHGFI_ICON))[b] {[b] pDC ->DrawIcon(10,10,stFileInfo.hIcon);[b] }[b] }
  [b] Example(2):同样功能,Use ExtractIcon Function[b] void CSampleView:: OnDraw(CDC *pDC)[b] {[b] HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T[b] ("NotePad.exe"),0);
  if (hIcon &&hIcon!=(HICON)-1)[b] pDC->DrawIcon(10,10,hIcon);[b] }[b] 【说明】关于如何得到系统文件的正确路径,象win.ini system32.ini等的路径,各种系统中具体的路径是不一样的。如:[b] 获得notepad.exe的路径正规上来说用GetWindowsDirectory 函数得到;[b] 如果是调用 win95下的画笔,应该用访问注册表的方法获得其路径;[b] 要作成一个比较考究的程序,考虑应该全面点.
  【另】[b] HINSTANCE AfxGetResourceHandle( );[b] Return Value:An HINSTANCE handle where the default resources of the application are loaded.
  4. 有关取得桌面句柄 GetDesktopWindow()
  MSDN中的例子:
  // 静态函数CWnd:: GetDesktopWindow 返回桌面窗口的指针。下例说明了MFC[b]void CFrameWnd::BeginModalState ()[b]{[b] //first count all windows that need to be disabled[b] UINT nCount=0;[b] HWND hWnd=:: GetWindow (:: GetDesktopWindow (), GW_CHILD);[b] while (hWnd!=NULL)[b] {[b] if (:: IsWindowEnabled (hwnd) &&[b] CWnd::FromHandlePermanent (hWnd)!=NULL &&[b] AfxIsDescendant (pParent->m_hWnd, hWnd) &&[b] :: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0) == 0)[b] {[b] ++nCount;[b] }[b] hWnd=:: GetWindow (hWnd, GW_HWNDNEXT);[b] }[b]}
  //用户的问题:下面程序取的不是同一程序的句柄,但是GetModuleFileName返回的结果一样请问为什莫
  HWND ChWnd;//子窗口句柄 [b]HWND hwDesktop=::GetDesktopWindow();//取得桌面句柄 [b]ChWnd=::GetWindow(hwDesktop,GW_CHILD);//取得桌面子句柄 [b]CString csTitle,csClass,csTm,mLookstring; [b]char szBuffer[255]; [b]while(ChWnd!=NULL)//循环取子句柄的同级句柄 [b]{ [b] if(::IsWindowVisible(ChWnd))//判断是否为可显示窗口 [b] { [b] ::GetWindowText(ChWnd,csTitle.GetBuffer(255),254); [b] ::GetClassName(ChWnd,csClass.GetBuffer(255),254); [b] csTitle.ReleaseBuffer();//标题 [b] csClass.ReleaseBuffer();//类名 [b] csTm.Format("%08X:",ChWnd); [b] if(csTitle=="") [b] { [b] mLookstring=csTm+csClass; [b] }else [b] { [b] mLookstring=csTm+csTitle; [b] } [b] //这里的窗口句柄不是同一个程序吧?(问题所在!)可是为什莫结果一样 [b] HINSTANCE hInstance = (HINSTANCE)::GetWindowLong(ChWnd,DWL_USER); [b] ::GetModuleFileName(hInstance, szBuffer, sizeof(szBuffer)); [b] MessageBox(szBuffer,mLookstring); [b] } [b] ChWnd=::GetWindow(ChWnd,GW_HWNDNEXT); [b]}
  回答:
  问题在于Win32下GetWindowLong(ChWnd,DWL_USER)总是返回当前程序运行的hInstance,所以你得到的文件名总是一个。所以你要用枚举所有"进程的程序名"来获得程序名。 [b] 
  === 再谈句柄于指针的区别
  许多开始学习VC的朋友,最多听说的两个词莫过于指针和句柄了。 [b]但是,确经常搞不清他们之间的区别。 [b]首先,句柄是一个窗口的标志,也就是所有从CWND类继承下来的,多有句柄这个成员。 [b]他能做的,也就是唯一代表一个桌面上的窗口罢了。而指针是一个地址,如果它指向了一个内存中的对象,那么就可以对它进行任意操作了,当然,并不局限于自己的应用程序,你如果能够获得别的应用程序的某个对象的指针,也可以进行操作。然而,如果要获得指针,首先,必须找到那个窗口的句柄,然后用函数FromHandle就可以得到他的指针了。
  === 问题1:
  如何在自定义的消息中发送一个字符串?例如: [b]SendMessage(MyWnd,WM_USERDEFINED, 0,0) [b]如何将字符串Buffer写入wParam或lParam?
  你可以把字符串的地址传递过去,因为地址正好是32位。如: [b]char s[256]; [b]SendMessage(MyWnd,WM_USERDEFINED, (WPARAM) s,0) [b]接收方只需要将wParam赋给一个char*就可以了。但此方法只能使用于在一个进程内部传递数据。 [b] 
  === 问题2: [b]1.在VC应用程序框架中,如何加入自己做的类,如何定义这个类的对象,我想在鼠标点击某个菜单项的时候才生成这个对象,做得到吗?(这个类的构造函数是带参数的)。 [b]2.消息发送函数: [b] PostMessage(HWND handle,WM_MYMESSAGE, [b] WPARAM wParam,LPARAM lParam) [b] 中: [b]第一个参数如何获得?[b]如果我的消息是在自己的应用程序中生成的,想发给应用程序的窗口让它显示某些数据(用TextOut函数),能做到吗?[b](也可以说是这样的问题:用Appwizard生成应用程序框架,在生成的类(如CView)中如何得到窗口的句柄,并放在PostMessage函数中。) [b]3.wParam,lParam,在消息响应函数中如何用?vc是怎样保证这两个数传到函数中的?问题比较多,谢谢! [b]水平: 刚入门
  回答:
  1、这个问题是肯定的。你可以使用ClassWizard定义类,也可以手工输入。如果类定义已经在某个文件中,只要使用Project|Add files将文件加入工程就可以了。要想定义类的对象,只要在你的菜单项的相应事件中就可以了。如: [b]{ [b]... [b]MyClass myObject("Hello"); [b]myObject.MyMethod(); [b]... [b]} [b]2、在你自己的程序中传递消息当然没有任何问题,只要你知道要调用的窗口类是从CWnd继承来的,你就可以使用GetSafeHwnd函数获得窗口句柄。不过一般在自己的同一个程序中有时不愿意使用自定义消息,因为太麻烦。你完全可以给要调用的类添加一个成员函数,只要想显示数据,直接调用这个成员函数不就可以了?何必使用PostMessage呢?一般只有在程序间调用,才愿意使用自定义消息。这时,你通常可以使用FindWindow获得窗口句柄(QA000251 "如何利用FindWindow()函数查找程序")。 [b]3、对于MFC已经定义了消息处理函数的消息,MFC会自动把wParam和lParam映射为更容易使用的方式。如OnMouseMove( UINT nFlags, CPoint point )。对于MFC不能自动处理的函数,如你使用ON_MESSAGE定义消息函数,则MFC会把wParam和lParam原原本本的传递给你的函数,不做任何处理。
  === 一个未公开的Win32 API函数:GetTaskmanWindow ()
  下例中还用到: GetProcAddress GetParent(hWnd)[b] HMODULE hUser32 = GetModuleHandle("user32");
  download
  // getaskmanwnd.cpp (Windows NT/2000)[b]//[b]// 利用一个未公开的Win32 API函数:GetTaskmanWindow,[b]// 对Windows的任务栏进行操作(显示/隐藏)。这个函数返回拥有任务栏按钮的窗口句柄。[b]//[b]// This example will show you how you can obtain a handle to the[b]// Windows Taskbar window.[b]//[b]// (c)1999 Ashot Oganesyan K, SmartLine, Inc[b]// [ft=#249ede,,, http://www.protect-me.com, http://www.codepile.com
  #i nclude [b]#i nclude
  [b]// User32!GetTaskmanWindow (NT specific!)[b]//[b]// This function returns a handle to the window that ownes the taskbar buttons[b]//[b]// HWND GetTaskmanWindow()[b]//[b]typedef HWND (WINAPI *PROCGETTASKMANWND)(void);
  [b]PROCGETTASKMANWND GetTaskmanWindow;
  [b]void main(int argc, char* argv[])[b]{[b]if (argc<2)[b]{[b]printf("Usage:\n\ngetaskmanwnd.exe S|H\n");[b]return;[b]}
  HMODULE hUser32 = GetModuleHandle("user32");[b]if (!hUser32)[b]return;
  GetTaskmanWindow = (PROCGETTASKMANWND)GetProcAddress(hUser32,"GetTaskmanWindow"); [b]if (!GetTaskmanWindow)[b]return;
  HWND hWnd = GetTaskmanWindow();
  if (!hWnd)[b]return;
  if (*argv[1]=="H" || *argv[1]=="h")[b]ShowWindow(GetParent(hWnd),SW_HIDE);[b]else[b]ShowWindow(GetParent(hWnd),SW_SHOW);
  }
[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值