第一章:Windows程序内部运行机制

来源:互联网 发布:朋友圈图片制作软件 编辑:程序博客网 时间:2024/05/20 13:15
编写Win32窗口应用程序,入口函数WinMain
步骤如下:
  1. 设计窗口类:WNDCLASS结构体
  2. 注册窗口类:RegisterClass
  3. 创建窗口:CreateWindow
  4. 显示并更新窗口:ShowWindow,UpdateWindow
  5. 消息循环:windows应用程序消息循环机制如图所示
  6. 编写窗口过程函数


(1)操作系统收到应用程序的窗口消息,将消息投递到该应用程序的消息队列中。
(2)应用程序在消息循环中调用GetMessage函数从消息队列中取出一条一条的消息。取出消息后,应用程序可以对消息进行一些预处理,例如,放弃对某些消息的响应,或者调用TranslateMessage产生新的消息。
(3)应用程序调用DispatchMessage,将消息回传给操作系统。消息是由MSG结构体对象来表示的,其中就包含了接收消息的窗口的句柄。因此,DispatchMessage函数总能进行正确的传递。
(4)系统利用WNDCLASS结构体的lpfnWndProc成员保存的窗口过程函数的指针调用窗口过程,对消息进行处理。

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK GongSaiProc(HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
  );


int WINAPI WinMain(HINSTANCE hInstance,      // handle to current instance
  HINSTANCE hPrevInstance,  // handle to previous instance
  LPSTR lpCmdLine,          // command line
  int nCmdShow              // show state
  )
{
    //设计窗口类
    WNDCLASS wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = GongSaiProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = NULL;
    wndclass.hCursor = NULL;
    wndclass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = "GongSai";

    //注册窗口类
    if(!RegisterClass(&wndclass))
    {
        return 0;
    }

    //创建窗口
    HWND hWnd = NULL;
    CREATESTRUCT cs;
    cs.lpCreateParams = NULL;
    cs.hInstance = hInstance;
    cs.hMenu = NULL;
    cs.hwndParent = NULL;
    cs.cx = 600;
    cs.cy = 400;
    cs.x = 0;
    cs.y = 0;
    cs.style = NULL;
    cs.lpszClass = "GongSai";
    cs.lpszName = "Gongsai";
    cs.dwExStyle = NULL;

    hWnd = CreateWindow("GongSai","GongSai",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,&cs);

    if(!hWnd)
    {
        return 0;
    }

    //显示屏更新窗口
    ShowWindow(hWnd,SW_SHOWNORMAL);
    UpdateWindow(hWnd);

    //消息循环
    MSG msg;

    BOOL bRet;

    while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
    { 
        if (bRet == -1)
        {
            // handle the error and possibly exit
            return 0;
        }
        else
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
    }


    return 0;
}

LRESULT CALLBACK GongSaiProc(  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
 )
{
    switch(uMsg)
    {
    case WM_CHAR:
        char szChar[20];
        sprintf(szChar,"char code is: %d",wParam);
        MessageBox(hwnd,szChar,"char",0);
        break;
    case WM_LBUTTONDOWN:
        MessageBox(hwnd,"mouse clicked","message",0);
        HDC hdc;
        hdc = GetDC(hwnd);   //不能再响应WM_PAINT消息时使用
        TextOut(hdc,0,50,"程序员之家",strlen("程序员之家"));
        ReleaseDC(hwnd,hdc);
        break;
    case WM_PAINT:
        HDC hDC;
        PAINTSTRUCT ps;
        hdc = BeginPaint(hwnd,&ps);  //只能在响应WM_PAINT消息使用
        TextOut(hDC,0,0,"重绘",strlen("重绘"));
        EndPaint(hwnd,&ps);
        break;
    case WM_CLOSE:
        if(IDYES == MessageBox(hwnd,"是否真的结束?","message",MB_YESNO))
        {
            DestroyWindow(hwnd);
        }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }

    return 0
}

结果如下:

建议自己动手编写,了解编写windows窗口应用程序的步骤,善于查看MSDN。

疑问:
窗口过程处理函数设置成回调函数的原因?
我的直观理解:回调函数定义在应用程序中,但使用者却是操作系统,这样确保了灵活性,因为回调函数的实现主体都是自己实现的,同时它很方便,接口固定,按照既定的格式去编写代码即可,像操作系统调用回调函数的过程对于我们来说是透明的,完全可以不用理会,当然这可能还牵涉到多线程编程的知识,目前未深入涉猎,不敢多讲。
0 0
原创粉丝点击