VC++的窗口句柄和窗口ID
句柄是窗口资源的标识,它标识资源在系统中所占用的内存块,应用程序通过窗口句柄对窗口进行操作。除了窗口句柄之外,任何一种资源都有它自己的句柄,比如光标句柄、位图句柄等。窗口ID是窗口在应用程序中的唯一标识,通过窗口ID可以获取窗口句柄。
-------------------------------------------------------------------------------------------------
VC++中控件的ID是什么概念?句柄又是什么?
这两个概念都是控件的标识,这两个概念可以从"内外两方面考虑", |
------------------------------------------------------------------------------------------------
ID--HANDLE--HWND三者之间的互相转换
id->句柄、、、、、hWnd = ::GetDlgItem(hParentWnd,id);
id->指针、、、、、CWnd::GetDlgItem();
句柄->id、、、、、id = GetWindowLong(hWnd,GWL_ID);
句柄->指针、、、、CWnd *pWnd=CWnd::FromHandle(hWnd);
指针->ID、、、、、id = GetWindowLong(pWnd->GetSafeHwnd,GWL_ID);
GetDlgCtrlID();
指针->句柄、、、、hWnd=cWnd.GetSafeHandle() or mywnd->m_hWnd;
////////////////////////////////////////////////////////////////////////////////////////////////
先通过::FindWindow()函数取得主对话框的句柄
函数原形如下:
HWND FindWindow(
LPCTSTR lpClassName, // 主窗口的类名
LPCTSTR lpWindowName // 窗口标题
);
这个函数的返回值是主窗口的句柄
然后在通过::FindWindowEx()函数取得子窗口的句柄
函数原形如下:
HWND FindWindowEx(
HWND hwndParent, // 父窗口的句柄
HWND hwndChildAfter, // 得到的子窗口的句柄
LPCTSTR lpszClass, // 子窗口类名
LPCTSTR lpszWindow // 子窗口标题
);
上面这个函数是通过父窗口的句柄取得子窗口的句柄,后面的两个参数可以选用其中之一
另一个设置成NULL即可!
////////////////////////////////////////////////////////////////////////////////////////////////
在VC的窗口类中有一成员变量:m_hWnd ,它代表这个窗口的句柄。因此在VC中通过一些得到窗口指针的函数,然后再访问它的成员变量,应该可以得到所要的句柄。
比如用这个函数得到窗口指针,然后访问它的m_hWnd 。
AfxGetMainWnd( );
//////////////////////////////////////////////////////////////////////////////////////////////
VC:如何根据文件名来获取程序进程和窗口句柄的代码:
根据系统进程中的模块名和运行文件名称的匹配来查找程序进程的代码如下(因为窗口类和窗口名都在变化,所以只能如此了)。
//做系统进程快照
Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
//找第一个进程
f = Process32First(Snapshot, &processListStr);
while(f)
{
char *t1="3SMeeting.exe"; //这是运行文件名
if (*processListStr.szExeFile ==*t1){
sprintf( szHello, "ProcessID:%X EXE:%s",processListStr.th32ProcessID,processListStr.szExeFile);
TextOut(hdc, rt.left, rt.top, szHello,strlen(szHello));
break;
}
f = Process32Next(Snapshot, &processListStr); //继续查找
}
CloseHandle(Snapshot);
在VC中获取其它窗口句柄的方法很多,但用FindWindow等要根据窗口类和窗口标题来查找得到窗口句柄,正好碰到窗口类和窗口标题都是不断变化的,下面的代码是我经过实践得到的。
根据窗口名的一部分来获取窗口的句柄,代码如下:
int i;
//以桌面为父窗口来查找第一个主窗口
hWndPrevious = GetWindow(GetDesktopWindow(),GW_CHILD);
LPTSTR m_pszExeName;
while (IsWindow(hWndPrevious))
{
int i=GetWindowTextLength(hWndPrevious);
GetWindowText(hWndPrevious,szHello,i);//获取窗口标题
//这里我的窗口中只有下面几个字是不变的
if (strstr(szHello,"当前用户数:")){
sprintf( szHello1, "Hwnd:%X Title:%s",hWndPrevious,szHello);
TextOut(hdc, rt.left, rt.top, szHello1,strlen(szHello1));
break;
//匹配,这时hWndPrevious就是所要找的窗口的句柄
}
hWndPrevious = GetWindow(hWndPrevious,GW_HWNDNEXT);
}
欢迎指正。
------------------------------------------------------------------------------------------------
windows使用两种字符集ansi和unicode,前者就是通常使用的单字节方式,但这种方式处理象中文这样的双字节字符不方便,容易出现半个汉字的情况。而后者是双字节方式,方便处理双字节字符。windows nt的所有与字符有关的函数都提供两种方式的版本,而windows 9x只支持ansi方式。_t一般同字常数相关,如_t("hello")。如果你编译一个程序为ansi方式,_t实际不起任何作用。而如果编译一个程序为unicode方式,则编译器会把"hello"字符串以unicode方式保存。_t和_l的区别在于,_l不管你是以什么方式编译,一律以以unicode方式保存。
------------------------------------------------------------------------------------------------
派生和继承
1.派生类的概念
以面向对象的程序设计的观点来看,继承表达的是对象类之间的相互关系。这种关系使得某类对象可以继承另外一类对象的特征和能力。如果一类对象继承了另一类对象的特征和能力,这个类就叫做所继承类的派生类。
1.1声明一个派生类的一般格式是:
class 派生类名:派生方式( public or private)基类名{
//派生类新增加或修改的数据和成员函数};
1.2派生类构造函数和析构函数的执行顺序
当派生类中不含对象成员时
●在创建派生类对象时,构造函数的执行顺序是:基类的构造函数→派生类的构造函数;
●在撤消派生类对象时,析构函数的执行顺序是:派生类的构造函数→基类的构造函数。
当派生类中含有对象成员时
●在定义派生类对象时,构造函数的执行顺序:基类的构造函数→对象成员的构造函数→派生类的构造函数;
●在撤消派生类对象时,析构函数的执行顺序:派生类的构造函数→对象成员的构造函数→基类的构造函数。
.
1.3派生类构造函数和析构函数的构造规则
当基类中无显式定义构造函数或有函数但无参数时派生类可以不向基类传递参数,甚至可以不定义构造函数;
当基类中有构造函数且含有参数时,派生类必须定义构造函数以提供把参数传递给基类构造函数的途径。
⑴派生类构造函数的一般格式为:
派生类::派生类构造函数名(参数表):基类构造函数名(参数表){
// 派生类新增成员
}
⑵当派生类中含有对象成员时,其构造函数的一般形式为:
派生类::派生类构造函数名(参数表):基类构造函数名(参数表),对象成员名(参数表),……对象成员名n(参数表)
{//新增数据初始化(不包括对象成员)
}
2.多重继承
前面我们介绍的派生类只有一个基类,称为单基派生或单一继承。在实际运用中,我们经常需要派生类同时具有多个基类,这种方法称为多基派生或多重继承。
2.1多重继承的声明:
在C++中,声明具有两个以上基类的派生类与声明单基派生类的形式类似,只需将要继承的多个基类用逗号分开即可。
在多重继承中,公有派生和私有派生对于基类成员在派生类的可访问性与单继承的规则相同。
另外,对基类成员的访问必须是无二义的,若两个基类中具有同名的数据成员或成员函数,使用成员名限定来消除二义性,若派生类中新增成员或成员函数与基类成员或成员函数同名,则派生类会覆盖外层同名成员,也须使用作用域分辨符。
2.2多重继承的构造函数和析构函数:
多重继承的构造函数的定义形式与单继承构造函数的定义形式类似,只有n个基类的构造函数之间用“,”分隔。
多重继承的构造函数的执行顺序与单继承构造函数的执行顺序相同,也是遵循先执行基类的构造函数,再执行对象成员的构造函数,最后执行派生类构造函数的原则。在多个基类之间,则严格按照派生类声明是从左到右的顺序来排列先后。而析构函数的执行顺序与构造函数的执行顺序相反。
2.3虚基类:
如果某个派生类的部分或全部直接基类是从另一个共同的基类派生而来,在这些基类中,从上一级基类继承来的成员就有相同的名称,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性,此时,可定义虚基类。这就要求在其直接基类的定义中,使用关键字virtual将那个共同的基类定义为虚基类,其语法形式如下:
class 派生类名: virtual 派生方式 基类
虚基类的初始化与一般的多重继承的初始化在语法上是一样的 ,但构造函数的调用顺序不同,虚基类构造函数的调用顺序是这样规定的:
1)在同一层次中,先调用虚基类的构造函数,接下来依次是非虚基类的构造函数,对象成员的构造函数,派生类的构造函数。
2)若同一层次中包含多个虚基类,这些虚基类的构造函数按对他们说明的先后次序调用
3)若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类构造函数。
3.注意
1.基类向派生类提供它的行为和结构,派生类负责正确初始化基类对象
2.要用正确的参数调用直接基类的构造函数,以作为每个派生类构造函数的一部分(讨论)
3.普通成员函数不能用这种语法调用基类方法
4.类只负责其直接基类的构造。但存在虚基类时有所不同
5.派生类构造函数的参数要包括自己使用的和基类需要使用的所用参数
6.派生类继承基类的行为和结构,但不继承构造函数和析构函数
7.要在派生类拷贝构造函数中调用基类的拷贝构造函数
8.要在派生类赋值运算符中调用基类的赋值运算符
9. 派生类析构函数并不明确调用基类的析构函数
10. 所用虚基类都由最后的派生类的构造函数所初始化。当创建对象时,将忽略子对象构造函数内部对虚基类构造函数的调用。
11.公有继承是继承的主要模式,私有继承只在特殊情况下用(如实现堆栈类可从列表类中继承,但它不是某种列表,重新导出私有基类的成员。)私有继承没有多态性。
12.在单一继承能实现目的时,不要用多重继承
13.继承的优点:代码重用,在正在运行的程序中加入新类和新功能(如卫星、病人监护),动态联编,多态性。
------------------------------------------------------------------------------------------------
事件是由应用程序触发的,而消息是操作系统感知到的应用程序的事件,该事件将被转换成消息发送到应用程序的消息队列中。消息可以由操作系统产生,也可以由另一个消息产生,消息的处理函数就是窗口过程函数。
消息是通过MSG结构来实现的,该结构的定义如下:
typedef struct {
HWND hwnd; //接收消息的窗口句柄,如果是线程消息,则为NULL
UINT message; //消息的标识
WPARAM wParam; //附件函数,其精确含义取决于消息成员的值
LPARAM lParam; //附件函数,其精确含义取决于消息成员的值
DWORD time; //消息被投递的时间
POINT pt; //消息被投递时光标在屏幕中的位置
} MSG, *PMSG;
-------------------------------------------------------------------------------------------------
1、要认识到在任何情况下都不能使用指向空值的引用。但指针可以给他赋空值。
2、在C++里,引用应被初始化。但指针可以是未初始化的指针(不过空指针合法但危险)。
3、不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空
4、指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。
总的来说,在以下情况下你应该使用指针,一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。
还有一种情况,就是当你重载某个操作符时,你应该使用引用。最普通的例子是操作符[]。这个操作符典型的用法是返回一个目标对象,其能被赋值。
VC++的窗口句柄和窗口ID的更多相关文章
- 根据获取的窗口句柄遍历窗口Edit控件
网上说遍历窗口控件有两种方法: 1),使用EnumChildWindows,没有深究, 学习网址如下:http://blog.sina.com.cn/s/blog_60ac1c4b010116 ...
- emwin之窗口ID的唯一性
@2019-04-30 [小记] emwin窗口ID是唯一的 emwin多次创建同一窗口,则窗口句柄不同,多次删除窗口采取LIFO机制,即最新创建的窗口被首先删除 获取多次创建同一窗口的ID,准确位置 ...
- ATL中窗口句柄与窗口过程的关联方法
ATL中采用了一种动态生成机器指令的方式进行窗口句柄与窗口对象进行关联,以是详细分析: CWindowImpl会在第一次调用Create时注册窗口类,该窗口类是的信息是在CWindowImpl的子类中 ...
- VC中窗口ID,句柄,指针三者相互转换函数【转】
ID--HANDLE--HWND三者之间的互相转换id->句柄 hWnd = ::GetDlgItem(hParentWnd,id);id->指针 CWnd:: ...
- VC.【转】窗口置于前台并激活的方法
1.VC 窗口置于前台并激活的方法 - CSDN博客.html https://blog.csdn.net/oXunFeng/article/details/52681279 2.(http://ww ...
- VC关于置顶窗口的方法小结
转摘自:http://blog.csdn.net/wirror800/article/details/4002381 将窗体置顶的方法有: //将窗体置顶的API函数 ::SetWindowPos(m ...
- VC中判断指定窗口是否被其他窗口遮挡
本来是想判断当前窗口是否在最前面,无奈办法用尽就是不行,于是想换个思路:判断指定窗口是否被其他窗口遮挡.然后掘网三尺,找到了这个: bool CTestTray2Dlg::IsCoveredByOth ...
- vc++高级班之窗口篇[4]---让程序只运行一个实例
大家都看过或者使用过类似只运行一个实例的程序,比如:QQ游戏.部分浏览器 等等! 让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建后,有窗口的程序在窗口创建前, 检查系统中是 ...
- VC++ 判断你的窗口是否置顶TopMost
大家可能已经知道,使你的窗口置顶(TopMost)或者总是最前(Always on Top)的方法: C++ Code 12345 // Make topmost , SWP_NOMOVE | ...
随机推荐
- day04_06 短路原则
True和False不能写成ture和false,不然会报错 not not True or False and not True 按照not>and>or来进行括号 (not (not ...
- [python工具][3]sublime常用配置 与操作指南
https://github.com/jikeytang/sublime-text http://zh.lucida.me/blog/sublime-text-complete-guide/
- [转]zsh快捷键记录
转自: http://wdxtub.com/2016/02/18/oh-my-zsh/ 使用技巧 连按两次Tab会列出所有的补全列表并直接开始选择,补全项可以使用 ctrl+n/p/f/b上下左右切换 ...
- 【Luogu】P3761城市(dfs)
题目链接 emmm我思维好水…… 想了一会lct发现好像不对,然后开始转DP稍微有一点思路,然后看了题解…… 首先可以枚举边,然后原树被你拆成了两个子树. 设D1D2是两个子树的直径,W1W2是子树内 ...
- 用JS实现倒计时(日期字符串作为参数)
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- BZOJ3098 Hash Killer II 【概率】
挺有意思的一题 就是卡一个\(hash\) 我们先取L大概几十保证结果会超出\(10^9 + 7\) 然后就随机输出\(10^5\)个字符 由题目的提示我们可以想到,如果我们有\(n\)个数,选\(k ...
- Codeforces963B - Destruction of a Tree
Portal Description 给出一个\(n(n\leq2\times10^5)\)个点的树,每次可以删除一个度数为偶数的点及其相连的边,求一种能够删掉整棵树的方案. Solution 简单起 ...
- WIFI万能钥匙协议分析
WIFI万能钥匙协议分析 需求: 上android 市场下载任意一款,wifi万能钥匙 软件,对其进行 协议分析和逆向,达成如下结果:通过对软件的分析,完成自动化爬虫,爬wifi万能钥匙的wifi库, ...
- 《快速开发》通过Maven创建WebService项目Hello World!
有多快? 整个过程3分钟.不用下载jar包,不用一步一步创建Web Project... 你需要的就是在Maven库里选一个archetype,然后一路Next~ 先看结果: 准备好了吗?我们起飞: ...
- SpringBoot重点详解--使用Junit进行单元测试
目录 添加依赖与配置 ApplicationContext测试 Environment测试 MockBean测试 Controller测试 情况一 情况二 方法一 方法二 本文将对在Springboo ...