c++中,添加了一个按钮,句柄为hButton,如何添加他的单击消息处理函数?

c++中,添加了一个按钮,句柄为hButton,如何添加他的单击消息处理函数?,第1张

#include <windowsh>

#define OK 10

#define Edit 11

HINSTANCE g_hInstance; //头文件

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); //窗口函数声明

char szClassName[]="高处寒"; //窗口结构体的名称

char szAppTitle[]="感觉大师浏览器"; //窗口的标题

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam , INT nCmdShow) //WinMain()函数的定义

{

HWND hMainWnd; //窗口句柄

MSG msg; //消息结构体

WNDCLASS winclass;//窗口结构体

g_hInstance=hInstance;

if(!hPrevInstance)

//判断是否已有应用程序的实例在运行,给窗口结构体的数据成员赋值来规定所要建立的窗口的特征

{

winclassstyle=CS_HREDRAW|CS_VREDRAW; //窗口风格

winclasslpfnWndProc=WndProc; //窗口的消息处理函数

winclasscbClsExtra=0; //窗口类无扩展

winclasscbWndExtra=0; //窗口实例无扩展

winclasshInstance=hInstance; //当前应用程序实例句柄

winclasshIcon=LoadIcon(NULL,IDI_APPLICATION); //窗口的最小化图标为缺省图标

winclasshCursor=LoadCursor(NULL,IDC_ARROW); //窗口采用箭头光标

winclasshbrBackground=CreateSolidBrush(RGB(255,255,0));//窗口背景色为白色

winclasslpszMenuName=NULL;//无窗口菜单

winclasslpszClassName=szClassName; //给窗口结构体命名

RegisterClass(&winclass); //注册窗口

}

//下面用CreateWindow()函数来建立窗口,并返回所建立窗口的句柄

hMainWnd=CreateWindow(

szClassName, //窗口结构体的名称

szAppTitle, //窗口的标题

WS_OVERLAPPEDWINDOW, //窗口风格为可重叠窗口

//下面四个参数代表窗口左上角x,y坐标和窗口的宽度与高度,都使用缺省值

CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

//下面参数分别为父窗口句柄、窗口菜单句柄、应用程序实例句柄和附加参数

NULL,NULL,hInstance,NULL);

ShowWindow(hMainWnd,SW_SHOWNORMAL); //显示窗口

UpdateWindow(hMainWnd); //更新窗口

//下面用While()循环来建立消息循环

while(GetMessage(&msg,NULL,0,0)) //获取消息,填充msg结构体

{

TranslateMessage(&msg); //翻译键盘消息

DispatchMessage(&msg); //向窗口函数发送消息,让窗口函数处理

}

return msgwParam;

}

LRESULT CALLBACK WndProc(HWND hMainwnd, UINT message, WPARAM wParam, LPARAM lParam) //窗口函数的定义

{

HDC hdc; //设备描述表

PAINTSTRUCT ps; //刷新区域

RECT rect; //矩形结构

HWND hEdit,hButton;

char messageleft[]="按下了鼠标左键!"; //单击鼠标左键,消息框将显示的提示内容

switch(message) //判断消息标识符

{

int wmId,wmEvent;

case WM_CREATE:

hEdit=CreateWindowEx(WS_EX_CLIENTEDGE,"Edit",0,WS_CHILD | WS_VISIBLE |BS_PUSHBUTTON,30,35,100,20,hMainwnd,(HMENU)Edit,

g_hInstance,0);

hButton=CreateWindow("Button","感觉一下",WS_CHILD | WS_VISIBLE |BS_PUSHBUTTON,130,35,65,20,hMainwnd,(HMENU)OK,

g_hInstance,0);

case WM_COMMAND:

wmId = LOWORD(wParam);

wmEvent = HIWORD(wParam);

switch(wmId){

case OK:

char str[400];

GetDlgItemText(hMainwnd,Edit,str,400);

MessageBox(0,str,"确定",MB_OK|MB_ICONINFORMATION);

}

break;

case WM_PAINT: //窗口重绘

{

hdc=BeginPaint(hMainwnd,&ps);

GetClientRect(hMainwnd,&rect); //获取客户区区域

rectbottom=recttop+50;

DrawText(hdc,TEXT("感觉一下,你就知道"),-1,&rect,DT_SINGLELINE| DT_CENTER|DT_VCENTER); //在客户区中央输出文字

EndPaint(hMainwnd,&ps);

break;

}

case WM_LBUTTONDOWN:

{

MessageBox(hMainwnd,messageleft,"使用API创建窗口",MB_OK|MB_ICONINFORMATION);

break;

}

case WM_DESTROY://关闭应用程序窗口时发出的消息

{

PostQuitMessage(0); //发出WM_QUIT消息,结束应用程序

return 0;

}

default :

break;

}

return DefWindowProc(hMainwnd,message,wParam,lParam); //其它消息交给Windows做默认处理

}

使用窗口函数,您可以通过计算每行周围窗口上的集合值来分析数据。结果集会返回表示一组行的摘要值。您可以使用窗口函数计算一家公司在一段指定时间内的销售数据的移动平均值。

除 LIST 以外的任何集合函数都可以与窗口函数联合使用。

示例

下面的示例显示了一个窗口函数。查询返回一个结果集,该结果集按部门划分数据,然后提供员工薪水的累计汇总(从在公司的时间最长的员工开始)。结果集只包括居住在加利福尼亚、犹他州、纽约或亚利桑那州的那些雇员。Sum Salary 列提供了雇员薪水的累计总额。

SELECT dept_id, emp_lname, start_date, salary,

SUM(salary) OVER (PARTITION BY dept_id

ORDER BY start_date

RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS "Sum_Salary"

FROM employee

WHERE state IN ('CA', 'UT', 'NY', 'AZ') AND dept_id IN ('100', '200')

ORDER BY dept_id, start_date;下面的表是查询的结果集。结果集按部门划分。

对于部门 100,来自加利福尼亚、犹他州、纽约或亚利桑那州的雇员的薪水累计总额是 $434,09169,而部门 200 的雇员的薪水累计总额是 $250,20000。

#include <tcharh>

#include <windowsh>

HINSTANCE _HInstance; // 应用程序句柄

TCHAR _Title[] = _T("简单文本框"); // 定义窗口的标题

TCHAR _WindowClass[] = _T("MySimpleTextBoxApp");// 主窗口类名

ATOM _RegisterClass(); // 注册主窗口类

HWND _CreateWindow(int nCmdShow); // 创建主窗口

LRESULT CALLBACK _WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // 主窗口消息处理函数

TCHAR _TextBoxClass[] = _T("MySimpleTextBox"); // 文本框的类名

ATOM _RegisterTextBoxClass(); // 注册文本框的类

HWND _CreateTextBoxWindow(HWND hParentWnd); // 创建文本框

LRESULT CALLBACK _TextBoxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // 文本框窗口消息处理函数

void _DrawText(HDC hDC); // 绘制文本

void _SetCaretPos(HWND hWnd); // 设置光标位置

void _UpdateWindow(HWND hWnd); // 更新窗口

// 一些常量定义

#define MAINWINDOW_WIDTH 400 // 主窗口宽度

#define MAINWINDOW_HEIGHT 200 // 主窗口高度

#define TEXTBOX_WIDTH 300 // 文本框宽度

#define TEXTBOX_HEIGHT 20 // 文本框高度

#define TEXTBOX_MAXLENGTH 1024 // 文本框中文本的最大长度

TCHAR _String[TEXTBOX_MAXLENGTH + 1] = _T(""); // 文本

int _StringPosition = ::_tcslen(_String); // 光标插入点所在的位置

int APIENTRY _tWinMain(HINSTANCE hInstance, // 当前的应用程序句柄

HINSTANCE hPrevInstance, // 前一个应用程序实例的句柄(在Win32上,始终为NULL)

LPTSTR lpCmdLine, // 命令行参数

int nCmdShow // 窗口的显示样式

)

{

_HInstance = hInstance;

_RegisterClass(); // 注册窗口类

if(_CreateWindow(nCmdShow) == NULL) // 创建窗口

return FALSE;

MSG msg;

while (::GetMessage(&msg, NULL, 0, 0)) // 从消息队列中获取消息

{

::TranslateMessage(&msg); // 转译一些特殊的消息

::DispatchMessage(&msg); // 执行消息处理

}

return (int)msgwParam;

}

// 注册应用程序窗口类

ATOM _RegisterClass()

{

WNDCLASSEX wc;

::ZeroMemory(&wc, sizeof(wc)); // 作为一步清空,是为了让未赋值的字段的默认值为(或NULL)

wccbSize = sizeof(wc);

wcstyle = CS_HREDRAW | CS_VREDRAW; // 指定当窗口横向和纵向的尺寸发生变化时都会重绘窗口

wchInstance = _HInstance;

wchbrBackground = (HBRUSH)( COLOR_APPWORKSPACE + 1); // 指定主窗口背景为“工作区域”系统颜色

wclpszClassName = _WindowClass; // 此为要注册的类名,创建窗口时要以此类名为标识符

wclpfnWndProc = _WndProc; // 此为处理窗口消息的函数

return ::RegisterClassEx(&wc); // 调用API函数注册窗口类

}

// 创建窗口

HWND _CreateWindow(int nCmdShow)

{

HWND hWnd = ::CreateWindow(_WindowClass, _Title, WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT, MAINWINDOW_WIDTH, MAINWINDOW_HEIGHT, NULL, NULL, _HInstance, NULL);

if(hWnd == NULL)

return NULL;

::ShowWindow(hWnd, nCmdShow);

::UpdateWindow(hWnd);

return hWnd;

}

// 窗口处理过程

LRESULT CALLBACK _WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

static HWND hTextBoxWnd;

switch (message)

{

case WM_CREATE: {

_RegisterTextBoxClass(); // 注册文本框的类

hTextBoxWnd = _CreateTextBoxWindow(hWnd); // 创建文本框

} break;

case WM_ACTIVATE: // 当窗口被激活时,将焦点设置在文本框上

::SetFocus(hTextBoxWnd);

break;

case WM_SETCURSOR: { // 设置光标形状

static HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW);

::SetCursor(hCursor);

} break;

case WM_DESTROY: // 应用程序被关闭

::PostQuitMessage(0);

break;

default:

return ::DefWindowProc(hWnd, message, wParam, lParam);

}

return (LRESULT)0;

}

// 注册文本框的类

ATOM _RegisterTextBoxClass()

{

WNDCLASSEX wc;

::ZeroMemory(&wc, sizeof(wc));

wccbSize = sizeof(wc);

wcstyle = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; // 指定当窗口尺寸发生变化时重绘窗口,并且响应鼠标双击事件

wchInstance = _HInstance;

wchbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // 指定窗口背景颜色为系统颜色“窗口背景”

wclpszClassName = _TextBoxClass; // 指定要注册的窗口类名,创建窗口时要以此类名为标识符

wclpfnWndProc = _TextBoxWndProc; // 处理窗口消息的函数

return ::RegisterClassEx(&wc); // 调用API函数注册文本框窗口

}

// 创建文本框

HWND _CreateTextBoxWindow(HWND hParentWnd)

{

// 之下代码是为了让文本框显示在父窗口中央,而计算位置

RECT parentWndRect;

::GetClientRect(hParentWnd, &parentWndRect); // 获取父窗口客户区的位置

int left = (parentWndRectright - TEXTBOX_WIDTH) / 2, top = (parentWndRectbottom - TEXTBOX_HEIGHT) / 2;

// 创建文本框

HWND hWnd = ::CreateWindow(_TextBoxClass, NULL, WS_CHILDWINDOW | WS_VISIBLE,

left, top, TEXTBOX_WIDTH, TEXTBOX_HEIGHT,

hParentWnd, NULL, _HInstance, NULL);

return hWnd;

}

// 文本框消息的处理过程

LRESULT CALLBACK _TextBoxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

switch (message)

{

case WM_PAINT: { // 绘制这里之所以加一对大括号,是为了让之下定义的变量局部化

static PAINTSTRUCT ps;

static RECT rect;

HDC hDC = ::BeginPaint(hWnd, &ps); // 开始绘制 *** 作

::GetClientRect(hWnd, &rect); // 获取客户区的尺寸

::DrawEdge(hDC, &rect, EDGE_SUNKEN, BF_RECT); // 绘制边框,EDGE_SUNKEN表示绘制样式为内嵌样式,BF_RECT表示绘制矩形边框

_DrawText(hDC); // 绘制文本

::EndPaint(hWnd, &ps); // 结束绘制 *** 作

} break;

case WM_SETFOCUS: { // 获得焦点

::CreateCaret(hWnd, (HBITMAP)NULL, 1, TEXTBOX_HEIGHT-5); // 创建光标

_SetCaretPos(hWnd); // 设置光标位置

::ShowCaret(hWnd); // 显示光标

} break;

case WM_KILLFOCUS: // 失去焦点

::HideCaret(hWnd); // 隐藏光标

::DestroyCaret(); // 销毁光标

break;

case WM_SETCURSOR: { // 设置光标形状

static HCURSOR hCursor = ::LoadCursor(NULL, IDC_IBEAM);

::SetCursor(hCursor);

} break;

case WM_CHAR: { // 字符消息

TCHAR code = (TCHAR)wParam;

int len = ::_tcslen(_String);

if(code < (TCHAR)' ' || len >= TEXTBOX_MAXLENGTH)

return 0;

::MoveMemory(_String + _StringPosition + 1, _String + _StringPosition, (len - _StringPosition + 1) sizeof(TCHAR));

_String[_StringPosition ++] = code;

_UpdateWindow(hWnd);

_SetCaretPos(hWnd);

} break;

case WM_KEYDOWN: { // 键按下消息

TCHAR code = (TCHAR)wParam;

switch (code)

{

case VK_LEFT: // 左光标键

if(_StringPosition > 0)

_StringPosition --;

break;

case VK_RIGHT: // 右光标键

if(_StringPosition < (int)::_tcslen(_String))

_StringPosition ++;

break;

case VK_HOME: // HOME 键

_StringPosition = 0;

break;

case VK_END: // END 键

_StringPosition = ::_tcslen(_String);

break;

case VK_BACK: // 退格键

if(_StringPosition > 0)

{

::MoveMemory(_String + _StringPosition - 1, _String + _StringPosition, (::_tcslen(_String)-_StringPosition + 1) sizeof(TCHAR));

_StringPosition --;

_UpdateWindow(hWnd);

}

break;

case VK_DELETE: { // 删除键

int len = ::_tcslen(_String);

if(_StringPosition < len)

{

::MoveMemory(_String + _StringPosition, _String + _StringPosition + 1, (::_tcslen(_String) - _StringPosition + 1) sizeof(TCHAR));

_UpdateWindow(hWnd);

}

} break;

}

_SetCaretPos(hWnd);

} break;

case WM_LBUTTONDOWN: { // 鼠标单击,设置光标位置

int x = LOWORD(lParam);

HDC hDc = ::GetDC(hWnd);

int strLen = ::_tcslen(_String), strPos = 0;

SIZE size;

for (strPos=0; strPos<strLen; strPos++)

{

::GetTextExtentPoint(hDc, _String, strPos, &size);

if(sizecx + 4 >= x)

break;

}

_StringPosition = strPos;

::GetTextExtentPoint(hDc, _String, strPos, &size);

::SetCaretPos(sizecx + 4, 3);

::ReleaseDC(hWnd, hDc);

} break;

default:

return ::DefWindowProc(hWnd, message, wParam, lParam);

}

return (LRESULT)0;

}

// 更新窗口

void _UpdateWindow(HWND hWnd)

{

RECT rect;

::GetClientRect(hWnd, &rect);

::InvalidateRect(hWnd, &rect, TRUE);

::UpdateWindow(hWnd);

}

// 绘制文本

void _DrawText(HDC hDC)

{

int len = ::_tcslen(_String);

::TextOut(hDC, 4, 2, _String, len);

}

// 设置光标位置

void _SetCaretPos(HWND hWnd)

{

HDC hDC = ::GetDC(hWnd);

SIZE size;

::GetTextExtentPoint(hDC, _String, _StringPosition, &size);

::SetCaretPos(4 + sizecx, 3);

::ReleaseDC(hWnd, hDC);

}

Win32程序主消息循环的标准写法是:

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

首先使用 GetMessage() 函数获取消息,然后用TranslateMessage()函数转化消息,这样做的目的是,获取一些按键消息(虚拟键如ESC、Ctrl、Atl、箭头等等)转化为ASCll字符的键产生WM_CHAR消息(这样系统才可以识别),DispatchMessage再将消息转发给系统。

比如:VK_RETURN 回车键对应的ASCll字符为0x0D

VK_RETURN 就是虚拟键消息,0x0D就是字符消息

连续调用的目的就是使你的程序一直在消息循环中,因为Windows程序运行的机制就是基于消息循环的,没有了消息循环程序就不能相应对它的 *** 作了。

补充:

WNDCLASS结构的第一个成员style表示窗口类的风格,它往往是由一些基本的风格通过位的“或” *** 作( *** 作符位“|”)组合而成。以下列出了一些常用的基本窗口风格:

CS_HREDRAW 如果窗口客户区宽度发生改变,重绘整个窗口

CS_VREDRAW 如果窗口客户区高度发生改变,重绘整个窗口

CS_DBLCLKS 能感受用户在窗口中的双击消息

CS_NOCLOSE 禁用系统菜单中的“关闭”命令

CS_OWNDC 为该窗口类的各窗口分配各自独立的设备环境

CS_CLASSDC 为该窗口类的各窗口分配一个共享的设备环境

CS_PARENTDC 指定子窗口继承其父窗口的设备环境

CS_SAVEBITS 把被窗口遮掩的屏幕图象部分作为位图保存起来。当该窗口被移动时,Windows使用被保存的位图来重建屏幕图象

CS_CLASSDC就表示为该窗口类的各窗口分配一个共享的设备环境

WM_COMMAND是从菜单选择一个索引、控件发送消息到父窗口、加速键被翻译时的消息,

WM_COMMAND的原型是:

WM_COMMAND wNotifyCode = HIWORD(wParam);

wID = LOWORD(wParam);

hwndCtl = (HWND) lParam;

wNotifyCode = HIWORD(wParam); 取高字节,如果该消息是从一个加速,这个参数1 。如果该消息是从菜单中,此参数为0

wID = LOWORD(wParam); 取低字节,菜单,控件,加速键的ID

hwndCtl = (HWND) lParam;如果该消息是来自控件的,则处理和控制发出信息。否则,这个参数是无效的

那么

switch (wmID)

{

case IDM_ABOUT:

break;

case IDM_EXIT:

break;

default:

return DefWindowProc(hWnd,message,wParam,lParam);

}

这个消息响应就是响应来自有ID的菜单,控件,加速键的消息

case IDM_ABOUT:

break;

case IDM_EXIT:

break;

default:

return DefWindowProc(hWnd,message,wParam,lParam);

IDM_ABOUT:这个是响应ID为IDM_ABOUT的菜单,控件,或加速键消息

DefWindowProc(hWnd,message,wParam,lParam);

这个函数是系统提供的一个窗口消息处理函数,使系统对用户的每个没有处理的消息进行默认处理,是任何发送到该窗口的消息均能得到合适的处理

建议:如果你对这些消息不了解的,建议你查看MSDN

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/12179795.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-21
下一篇2023-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存