鱼C论坛

 找回密码
 立即注册

恒信网络科技

https://fishc.com.cn/?210680

Windows API一日一练(6)WindowProc和DefWindowProc函数

热度 1已有 694 次阅读2014-4-15 17:50 |个人分类:vc++学习

Windows操作系统里,当窗口显示之后,它就可以接收到系统源源不断地发过来的消息,然后窗口就需要处理这些消息,因此就需要一个函数来处理这些消息。在API里定义了一个函数为回调函数,当系统需要向窗口发送消息时,就会调用窗口给出的回调函数WindowProc,如果WindowProc函数不处理这个消息,就可以把它转向DefWindowProc函数来处理,这是系统的默认消息处理函数。当你按下菜单,或者点击窗口时,窗口需要运行这个消息处理函数。
函数WindowProc声明如下:
LRESULT CALLBACK WindowProc(          HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
);
hwnd是当前窗口的句柄。
uMsg是系统发过来的消息。
wParam是消息参数。
lParam是消息参数。
 
这个函数一定是静态函数,也就是全局函数,在编译时已经确定了地址。由于它需要设置在注册的窗口类型里,如下:
// First.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
HINSTANCE hinst;  
TCHAR szTitle[] = "这是一个测试窗口";  //定义窗口标题
TCHAR szWindowClass[] = "szClassName"; // 定义窗口类名
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //申明消息处理回调函数
ATOM MyRegisterClass(HINSTANCE hInstance); // 申明注册函数: MyRegisterClass()
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  // TODO: Place code here.
 MyRegisterClass(hInstance); //用写好的注册函数注册
 InitInstance(hInstance, SW_SHOWNORMAL); //调用写好的初始华函数
MSG msg;
 while (GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return 0;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
 WNDCLASSEX wcex;      //定义一个窗口结构的对象wcex
 
 wcex.cbSize = sizeof(WNDCLASSEX);  //设置窗口结构的大小
 
 wcex.style = CS_HREDRAW | CS_VREDRAW; //设置窗口类型
 wcex.lpfnWndProc = WndProc;   //设置窗口消息处理函数WndProc
 wcex.cbClsExtra = 0;     //设置窗口类型的扩展为空
 wcex.cbWndExtra = 0;     //设置窗口类型的扩展为空
 wcex.hInstance = hInstance;   //设置窗口当前实例句柄
 wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);  //设置窗口图标
 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //设置光标为箭头
 wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  //设置窗口背景颜色
 wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); //设置窗口菜单这里设置为空也可用MAKEINTRESOURCE(菜单ID)取到
 wcex.lpszClassName = szWindowClass; //设置窗口类名
 
 wcex.hIconSm = NULL; //设置窗口小图标可用LoadIcon(wcex.hInstance, MAKEINTRESOURCE(图标ID))取到
 
 return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
 hinst = hInstance;
 HWND hWnd;
 
 
 hWnd = CreateWindow(szWindowClass,   // szWindowClass是窗口注册名称
      szTitle,    // 窗口显示的标题
      WS_OVERLAPPEDWINDOW, // 窗口显示类型
      CW_USEDEFAULT,   // 缺省的左上角坐标
      CW_USEDEFAULT,   // 窗口左上角坐标,由于X坐标设置为缺省的坐标了
      CW_USEDEFAULT,   // 设置窗口的宽度。使用缺省值
      CW_USEDEFAULT,   // 设置窗口的高度
      NULL,     // 父窗口设置为无
      NULL,     // 主菜单设置为无
      hInstance,    // 窗口当前实例句柄
      NULL);     // 传递给窗口的自定义参数
 if (!hWnd)
 {
  return FALSE;
 }
 
 ShowWindow(hWnd,nCmdShow);
 UpdateWindow(hWnd);
 return TRUE;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) //编写消息处理回调函数
{
 int wmid,wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;
 switch(uMsg)
 {
 case WM_COMMAND:
  wmid = LOWORD(wParam);
  wmEvent = HIWORD(wParam);
  
  // 菜单选项命令响应
  switch(wmid)
  {
  case IDM_ABOUT:
    DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, NULL); 
   break;
  default:
   return DefWindowProc(hwnd, uMsg, wParam, lParam);
  }
  break;
  case WM_PAINT:
   hdc = BeginPaint(hwnd, &ps);
   EndPaint(hwnd, &ps);
   break;
  case WM_DESTROY:
   PostQuitMessage(0);
   break;
 default:
  return DefWindowProc(hwnd, uMsg, wParam, lParam);
 }
 
}
了窗口消息处理函数,就可以响应不同的消息,实现各种各样的功能。

路过

雷人
1

握手

鲜花

鸡蛋

刚表态过的朋友 (1 人)

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-5 16:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

返回顶部