Win 32 编程之按钮消息响应(代码小错误修复)
最近不想用MFC写东西了,有没有安装Qt和其他图形化开发环境,只能捣鼓API了。于是乎,就有了以下的学习--
首先,老套的创建个Windows窗口,由于自己有点小懒,就直接用Hello Word的源码了。
#include <windows.h>
#include <stdio.h> // 窗口过程函数
LRESULT CALLBACK WinSunProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
) {
// 窗口类
WNDCLASS wndcls;
wndcls.cbClsExtra = ; // 类附加内存
wndcls.cbWndExtra = ; // 窗口附加内存
wndcls.hbrBackground = (HBRUSH) GetStockObject(COLOR_WINDOW); // 背景画刷句柄
wndcls.hCursor = LoadCursor(NULL, IDC_ARROW); // 窗口光标句柄
wndcls.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 窗口图标句柄
wndcls.hInstance = hInstance; // 包含窗口过程函数的程序实例
wndcls.lpfnWndProc = WinSunProc; // 只想窗口过程函数的指针
wndcls.lpszClassName = "CRoot"; // 窗口类名称
wndcls.lpszMenuName = NULL; // 菜单资源
wndcls.style = CS_HREDRAW | CS_VREDRAW; // 窗口样式
RegisterClass(&wndcls); // 创建窗口, 定义一个变量用来保存成功创建窗口后返回的句柄
HWND hwnd;
hwnd = CreateWindow( // 窗口创建成功时返回为窗口分配的句柄 失败时返回NULL
"CRoot", // 窗口类名
"Hello World", // 窗口名字
WS_CAPTION|WS_SYSMENU, // 窗口样式
CW_USEDEFAULT, CW_USEDEFAULT, // 窗口左上角坐标
, , // 窗口宽高
NULL, // 父窗口句柄
NULL, // 窗口菜单句柄
hInstance, // 窗口所属应用程序实例
NULL // WM_CREATE消息附加参数lParam传入的数据指针
); // 显示及刷新窗口
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd); // 定义消息结构体
MSG msg;
while (GetMessage( // WM_QUIT消息返回0 错误返回-1
&msg, // 指向消息的结构体
NULL, // 指定接收属于哪一窗口的消息 通常设为NULL,用来接收属于调用线程的所有窗口的窗口消息
, // 获取消息的最小值 通常为0
)) // 获取消息的最大值 都设为0表示接收所有消息
{
TranslateMessage(&msg); // 将虚拟消息转换为字符消息 投递到调用线程的消息队列中 下次调用GetMessage时被取出
DispatchMessage(&msg); // 将消息传递给操作系统 由操作系统调用窗口过程函数对消息进行处理
}
return msg.wParam;
} // 窗口过程函数
LRESULT CALLBACK WinSunProc(
HWND hwnd, // 窗口句柄
UINT uMsg, // 消息代码
WPARAM wParam, // 附加参数
LPARAM lParam
)
{
switch(uMsg)
{
case WM_CHAR:
char szChar[];
sprintf(szChar, "char code is %d", wParam);
MessageBox(hwnd, szChar, "char", );
break; default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
} return ;
}
然后,我们要在消息循环里面添加创建Button的代码,因为Button是一个子窗口,所以创建方式也如同创建窗口一样,使用CreateWindow()函数。
而,此窗口要一开始跟随父窗口出现,所以要在父窗口创建时创建该Button。嗯,所以要在窗口过程函数里面监听下WM_CREATE消息。
代码片段:
switch(uMsg)
{
case WM_CHAR:
char szChar[];
sprintf(szChar, "char code is %d", wParam);
MessageBox(hwnd, szChar, "char", );
break;
case WM_CREATE:
CreateWindowEx(,"Button","按钮1",WS_VISIBLE|WS_CHILD,,,,,hwnd,(HMENU),,); default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
这里要说明一下啦,一开始我也搞得晕晕乎乎,不知道怎么搞Button的消息事件,这里我们用Button的ID啦。先看下微软的MSDN关于CreateWindow()函数
HWND WINAPI CreateWindow(
_In_opt_ LPCTSTR lpClassName,
_In_opt_ LPCTSTR lpWindowName,
_In_ DWORD dwStyle,
_In_ int x,
_In_ int y,
_In_ int nWidth,
_In_ int nHeight,
_In_opt_ HWND hWndParent,
_In_opt_ HMENU hMenu,
_In_opt_ HINSTANCE hInstance,
_In_opt_ LPVOID lpParam
);
关键点在参数HMENU hWndParent,第一眼一看是不是感觉像菜单?不错啦~确实在菜单中用到的。进一步看他的解释
hMenu [in, optional]
Type: HMENU
A handle to a menu, or specifies a child-window identifier depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.
红色选中大体意思说,当在做一个子窗口的时候,这个参数就是一个整形表示,用于标识这个子窗口,提供父窗口的消息处理。总的来说就是所谓的控件ID啦~
既然有标识,就好办啦,我们就判断是不是他,若是这个按钮,我们就让他响应相应的操作啦~~
但是怎么知道按钮被Click了呢?我们又得监听另一个消息WM_COMMAND,它有两个参数,其中一个就传输了所谓的控件ID
wParam
For a description of this parameter.
lParam
For a description of this parameter.
我们可以判断他如果是这个按钮的ID,我们就让他干某些事情。我们首先要转换下wParam的类型,否则和我们写的ID的类型不一样的。
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ()://之前我们创建按钮时,写的ID为0
//功能代码 //....... break; //...更多代码 }
好了,整体框架差不多完工啦,自己再加下代码啥的就没问题了。在这里,我再次浪费下篇幅,给出完整代码:
关于wmId一开始写程序没有编译,因为逻辑错误,未有注意到,忘记声明他了。为了防止被default给忽略掉,我们把他写在switch(uMsg)之前。
#include <windows.h>
#include <stdio.h>
#include <Windef.h> // 窗口过程函数
LRESULT CALLBACK WinSunProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
) {
// 窗口类
WNDCLASS wndcls;
wndcls.cbClsExtra = ; // 类附加内存
wndcls.cbWndExtra = ; // 窗口附加内存
wndcls.hbrBackground = (HBRUSH) GetStockObject(COLOR_WINDOW); // 背景画刷句柄
wndcls.hCursor = LoadCursor(NULL, IDC_ARROW); // 窗口光标句柄
wndcls.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 窗口图标句柄
wndcls.hInstance = hInstance; // 包含窗口过程函数的程序实例
wndcls.lpfnWndProc = WinSunProc; // 只想窗口过程函数的指针
wndcls.lpszClassName = "CRoot"; // 窗口类名称
wndcls.lpszMenuName = NULL; // 菜单资源
wndcls.style = CS_HREDRAW | CS_VREDRAW; // 窗口样式
RegisterClass(&wndcls); // 创建窗口, 定义一个变量用来保存成功创建窗口后返回的句柄
HWND hwnd;
hwnd = CreateWindow( // 窗口创建成功时返回为窗口分配的句柄 失败时返回NULL
"CRoot", // 窗口类名
"Hello World", // 窗口名字
WS_CAPTION|WS_SYSMENU, // 窗口样式
CW_USEDEFAULT, CW_USEDEFAULT, // 窗口左上角坐标
, , // 窗口宽高
NULL, // 父窗口句柄
NULL, // 窗口菜单句柄
hInstance, // 窗口所属应用程序实例
NULL // WM_CREATE消息附加参数lParam传入的数据指针
); // 显示及刷新窗口
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd); // 定义消息结构体
MSG msg;
while (GetMessage( // WM_QUIT消息返回0 错误返回-1
&msg, // 指向消息的结构体
NULL, // 指定接收属于哪一窗口的消息 通常设为NULL,用来接收属于调用线程的所有窗口的窗口消息
, // 获取消息的最小值 通常为0
)) // 获取消息的最大值 都设为0表示接收所有消息
{
TranslateMessage(&msg); // 将虚拟消息转换为字符消息 投递到调用线程的消息队列中 下次调用GetMessage时被取出
DispatchMessage(&msg); // 将消息传递给操作系统 由操作系统调用窗口过程函数对消息进行处理
}
return msg.wParam;
} // 窗口过程函数
LRESULT CALLBACK WinSunProc(
HWND hwnd, // 窗口句柄
UINT uMsg, // 消息代码
WPARAM wParam, // 附加参数
LPARAM lParam
)
{
WORD wmId = LOWORD(wParam);
//WORD wmEvent = HIWORD(wParam);
switch(uMsg)
{
/*case WM_CHAR:
char szChar[20];
sprintf(szChar, "char code is %d", wParam);
MessageBox(hwnd, szChar, "char", 0);
break;*/
case WM_CREATE:
CreateWindowEx(,"Button","按钮1",WS_VISIBLE|WS_CHILD,,,,,hwnd,(HMENU),,);
break;
case WM_COMMAND:
switch (wmId)
{
case ://(HMENU) 和创建中的id对应
//这里写你要让按钮实现的功能
MessageBoxA(NULL,"Hello Button!","My TestProject",MB_OK);
}
break; default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
} return ;
}
目前已经在GNU GCC Compiler成功!
Win 32 编程之按钮消息响应(代码小错误修复)的更多相关文章
- 解决视图状态消息验证代码 (MAC) 错误
https://blog.csdn.net/bingtingabc/article/details/49148745 2015年10月15日 10:05:56 bingtingabc 阅读数:3397 ...
- Java中用FileInputStream和FileOutputStream读写txt文件,文件内容乱码的问题,另附循环代码小错误
乱码问题大概就是编码格式不一样,搜了很多都是这么说的,修改编码解决乱码问题链接: https://blog.csdn.net/weixin_42496466/article/details/81189 ...
- MFC 自绘按钮 消息响应
单检测到按下消息时,发送一个消息 m_pParent->PostMessage(WM_COMMAND, IDC_BUTTON1); 然后再在消息映射里建立映射. ON_COMMAND(IDC_B ...
- 那些年,被我蠢哭了的php代码小错误~~~
首先,我爱敲代码!!!而且我很喜欢修改bug,在看到那些bug的时候,我是兴奋的,毕竟当你解决这个bug之后感觉是很爽的. 在学习的过程中,看到无数的bug,有一些错误是很微小的,一般在PHP中都能通 ...
- MFC动态按钮的创建及其消息响应(自定义消息)
动态按钮(多个)的创建: 1.在类中声明并定义按钮控件的ID #define IDC_D_BTN 10000 2.在类的OnInitDialog()函数中动态创建按钮(建立按钮对象时最好建立对象的指针 ...
- MFC动态按钮的创建及其消息响应 和 自定义消息
原文链接: http://www.cnblogs.com/gaohongchen01/p/4046525.html 动态按钮(多个)的创建: 1.在类中声明并定义按钮控件的ID #define IDC ...
- 【Windows编程】入门篇——win 32窗口的hello word!
✍ Windows编程基础 1.Win 32应用程序基本类型 1) 控制台程序 不需要完善的windows窗口,可以使用DOS窗口方式显示 2) Win 32窗口程序 包含窗口的程序,可以通过窗 ...
- 为duilib的MenuDemo增加消息响应,优化代码和显示效果
转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/38253297 第一部分 我在前一段时间研究了怎么制作duilib的菜单, ...
- MFC控件编程之 按钮编辑框.静态文本的使用,以及访问控件的七种方法.
MFC控件编程之 按钮编辑框.静态文本的使用以及访问控件的七种方法. 一丶按钮.静态文本的通用属性. 他们都有一个属性.就是可以输入标题内容.以及可以自定义控件ID. 创建一个MFC Dlg对话框. ...
随机推荐
- Data access between different DBMS and other txt/csv data source by DB Query Analyzer
1 About DB Query Analyzer DB Query Analyzer is presented by Master Genfeng,Ma from Chinese Mainl ...
- Android Studio: You need to use a Theme.AppCompat theme (or descendant) with this activity.
错误描述为: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with ...
- 安卓 LayoutInflater参数作用
方法重载1 public View inflate (int resource, ViewGroup root, boolean attachToRoot) 方法重载2 public View inf ...
- Swift:Foundation框架中的NS前缀的由来
可能大家对于著名的NS前缀的由来有一些疑问. 绝大多数这些NS前缀的类是NeXTSTEP操作系统中Foundation框架里的一部分,而该操作系统是OS X的基础. NeXTSTEP的程序员对它们的类 ...
- 剑指Offer——顺丰笔试题+知识点总结
剑指Offer--顺丰笔试题+知识点总结 情景回顾 时间:2016.10.16 19:00-20:40 地点:山东省网络环境智能计算技术重点实验室 事件:顺丰笔试 知识点总结 快排 霍尔排序(快排) ...
- 基于Nginx服务器和iOS9的HTTPS安全通信
简介 在网络通信中,使用抓包软件可以对网络请求进行分析,并进行重放攻击,重放攻击的解决方案一般是使用一个变化的参数,例如RSA加密的时间戳,但考虑到网络传输时延,时间戳需要有一定的误差容限,这样仍然不 ...
- cassandra eclipse 环境构建
摘要 本文主要介绍如何在eclipse中搭建cassandra环境 更多cassandra,nosql 相关知识请访问http://www.webpersonaldeveloper.cn 正文 1.f ...
- Swift中如何转换不同类型的Mutable指针
在Swift中我们拥有强大高级逻辑抽象能力的同时,低级底层操作被刻意的限制了.但是有些情况下我们仍然想做一些在C语言中的hack工作,下面本猫就带大家看一看如何做这样的事. hacking is ha ...
- CVS简介
CVS - Concurrent Versions System(并发版本管理系统)是一个版本控制管理系统,它是SVN出现之前最为广泛使用的一个版本控制系统. CVS的优点就不多说了,总之没有它,早期 ...
- 使用java命令重启tomcat
public static void restartMyTomcat() { String location=ConfigUtil.getRestartLocation(); createCmdFil ...