• 05 Windows编程——Windows程序框架


    源码

     1 #include<Windows.h>
     2 
     3 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
     4 
     5 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
     6 {
     7     WNDCLASS WndClass;
     8     TCHAR* ClassName = TEXT("MyClass");
     9     HWND hwnd;
    10     MSG msg;
    11 
    12     WndClass.cbClsExtra = 0;
    13     WndClass.cbWndExtra = 0;
    14     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    15     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    16     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    17     WndClass.hInstance = hInst;
    18     WndClass.lpfnWndProc = WindProc;
    19     WndClass.lpszClassName = ClassName;
    20     WndClass.lpszMenuName = NULL;
    21     WndClass.style = CS_VREDRAW | CS_HREDRAW;
    22 
    23     if (!RegisterClass(&WndClass))
    24     {
    25         MessageBox(NULL, TEXT("Gegister Class Fail!!"), TEXT("error"), MB_OK);
    26         return 0;
    27     }
    28 
    29     hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL);
    30     if (hwnd == NULL)
    31     {
    32         MessageBox(NULL, TEXT("Create Window Fail!!"), TEXT("error"), MB_OK);
    33         return 0;
    34     }
    35     ShowWindow(hwnd, nShow);
    36     UpdateWindow(hwnd);
    37 
    38     while (GetMessage(&msg,NULL,0,0))
    39     {
    40         TranslateMessage(&msg);
    41         DispatchMessage(&msg);
    42     }
    43 
    44     return 0;
    45 }
    46 
    47 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    48 {
    49     switch (message)
    50     {
    51     case WM_DESTROY:
    52         PostQuitMessage(0);//发送WM_QUIT消息
    53         return 0;
    54     default:
    55         break;
    56     }
    57 
    58     return DefWindowProc(hwnd, message, wParam, lParam);
    59 }
    View Code

     LoadIcon

      载入图示供程式使用。
    LoadCursor
      载入鼠标供程序使用。
    GetStockObiect
      取得一个图形对象(在这个例子中,是取得绘制视窗背景的画刷物件)。
    RegisterClass

      为程序视窗注册窗口类。

    Create Window
      根据窗口类建立一个视窗。
    ShowWindow

      在萤幕上显示窗口。

    UpdateWindow
      更新窗口。
    GetMessage
      从程序消息队列获取消息。
    TranslateMessage
      将虚拟密钥消息转换为字符消息。字符消息被发布到调用线程的消息队列,以便在线程下次调用GetMessage或PeekMessage函数时读取

    DispatchMessage

      将消息发送到窗口过程。它通常用于分派由GetMessage函数检索的消息。

    PostQuitMessage
      向系统指示线程已发出终止请求(退出)。它通常用于响应WM_DESTROY消息。

    LoadCursor

    从与应用程序实例关联的可执行文件(.EXE)加载指定的游标资源。
    注意此函数已被LoadImage函数取代。

    LoadIcon

    从与应用程序实例关联的可执行文件(.EXE)加载指定的游标资源。
    注意此函数已被LoadImage函数取代。

    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
    );

    DispatchMessage这里调用的是我们自定义的消息处理函数WindProc

    PostQuitMessage(0)发送WM_QUIT消息,使GetMessage函数返回值为零,从而退出while循环。

     WIndows窗体程序的一生 ,大部分时间都在消息循环中度过。

     下面代码创建一个空白窗口程序,没有关闭按钮,只能Alt+F4关闭

    GetSystemMetrics是一个计算机函数,该函数只有一个参数,称之为「索引」,这个索引有75个标识符,通过设置不同的标识符就可以获取系统分辨率、窗体显示区域的宽度和高度、滚动条的宽度和高度。

     1 #include<Windows.h>
     2 
     3 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
     4 
     5 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
     6 {
     7     WNDCLASS WndClass;
     8     TCHAR* ClassName = TEXT("MyClass");
     9     HWND hwnd;
    10     MSG msg;
    11 
    12     WndClass.cbClsExtra = 0;
    13     WndClass.cbWndExtra = 0;
    14     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    15     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    16     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    17     WndClass.hInstance = hInst;
    18     WndClass.lpfnWndProc = WindProc;
    19     WndClass.lpszClassName = ClassName;
    20     WndClass.lpszMenuName = NULL;
    21     WndClass.style = CS_VREDRAW | CS_HREDRAW;
    22 
    23     if (!RegisterClass(&WndClass))
    24     {
    25         MessageBox(NULL, TEXT("Gegister Class Fail!!"), TEXT("error"), MB_OK);
    26         return 0;
    27     }
    28 
    29     hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInst, NULL);
    30     if (hwnd == NULL)
    31     {
    32         MessageBox(NULL, TEXT("Create Window Fail!!"), TEXT("error"), MB_OK);
    33         return 0;
    34     }
    35     ShowWindow(hwnd, nShow);
    36     UpdateWindow(hwnd);
    37 
    38     while (GetMessage(&msg,NULL,0,0))
    39     {
    40         TranslateMessage(&msg);
    41         DispatchMessage(&msg);
    42     }
    43 
    44     return 0;
    45 }
    46 
    47 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    48 {
    49     switch (message)
    50     {
    51     case WM_DESTROY:
    52         PostQuitMessage(0);//发送WM_QUIT消息
    53         return 0;
    54     default:
    55         break;
    56     }
    57 
    58     return DefWindowProc(hwnd, message, wParam, lParam);
    59 }
    View Code

    窗口过程

    LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

    LRESULT CALLBACK WindowProc(
      _In_ HWND   hwnd,
      _In_ UINT   uMsg,
      _In_ WPARAM wParam,
      _In_ LPARAM lParam
    );

    hwnd:窗口过程可以为基于同一窗口类创建的多个窗口处理消息。通过hwnd 参数,窗口过程就可获知到底是哪一个窗口正在接收消息。

    message:具体某一Windows消息,例如VM_SIZE

    wParam、lParam提供消息相关的附加参数。以message为VM_SIZE为例,

    wParam 参数取值可为SIZE RESTORED、SIZE_MINIMIZED、SIZE MAXIMIZED、SIZE_MAXSHOW 或 SIZE MAXHIDE

    IParam参数中包含该窗口的新尺寸,窗口的新宽度(一个16位的值)和新高度(也是一个16位的值)被组合在32位的IParam参数中。头文件WINDEFH中定义了一些宏便于从IParam中提取这两个值。

    消息从何而来:

    消息来自于用户的输入;消息来自于系统;


    消息被存放在那里:

    消息被存放在每个线程的消息队列中。


    消息如何被线程取出:

    GetMessage函数,PeekMessage.

    GetMessage在取消息的时候,如果消息队列是空的。GetMessage函数将阻塞线程,知道消息队列有一个消息,GetMessage才返回

    PeekMessage如果消息队列里面有消息,其行为和GetMessage一样。如果消息队列为空,PeekMessage立即返回


    消息队列是否先进先出,Fl-FO

    对大多数消息而言,是FIFO
    但是消息队列会对特殊满息进行处理,例如WM_PAINT,WM_TIMER,WM_QUIT。


    消息是否必须经过消息队列:

    否,有些消息被直接发送给窗口,不经过消息队列,例如,激活窗口的消息。

    命名约定

    lpfn 指向函数的长指针

    cb 字节数

    lpsz 指向以零结束的字符串的长指针

  • 相关阅读:
    使用Atlas简化客户端Ajax编程(Atlas 介绍)
    CheckBoxList 的数据绑定及数据获取
    ASP.NET 中数据库操作初步
    弹出对话框的同时保持页面的显示
    .net中常用的命名空间解释
    Atlas—微软的Ajax工具包(初学者必看)
    链接数据库类 DB.CS
    顶贴个性图片生成
    推荐10多个优秀的设计资源的网站
    Linux基本命令大全
  • 原文地址:https://www.cnblogs.com/kelamoyujuzhen/p/9300449.html
Copyright © 2020-2023  润新知