Windows编程入门——从一个简单的窗口说起


***【在线视频教程】***

好文章,来自【福优学苑@音视频+流媒体】

简介

#include <windows.h>
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MessageBox(NULL,"苟利国家生死以,岂因祸福避趋之","念诗",MB_OK);
    return 0;
}


这就是最简单的一个Win32程序,里面有很多声明都是以前在C/C++学习中没有见到过的。


WinMain():是和以往编程中的main()等价的东西.这是程序开始执行的入口;


HINSTANCE hInstance:程序可执行模块的句柄;


HINSTANCE hPrevInstance:总是为NULL;


LPSTR lpCmdLine:命令行参数组成的一个单字符串,不包括程序名;


int nCmdShow:要传递给ShowWindow()的一个整数。


MessageBox


主程序中出现的MessageBox()原型为:int WINAPI MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)


其实是根据Unicode的定义来的:


WINUSERAPI int WINAPI MessageBoxA(
 
HWND hWnd,
 
LPCSTR lpText,
 
LPCSTR lpCaption,
 
UINT uType);
 
 
WINUSERAPI int WINAPI MessageBoxW(
 
HWND hWnd,
 
LPCWSTR lpText,
 
LPCWSTR lpCaption,
 
UINT uType);
 
 
#ifdef UNICODE
 
#define MessageBox MessageBoxW//如果启用Unicode库,就用MessageBoxW
 
#else
 
#define MessageBox MessageBoxA//否则,就用MessageBoxA
 
#endif

WndProc()

单单只有一个窗口未免也太low了,我们可以增加一些互动元素,比如对于鼠标点击的处理。


这时我们可以尝试着把WM_LBUTTONDOWN添加到WndProc()中,看看能够发生什么


WndProc()部分的完整代码如下:



LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_LBUTTONDOWN:
    {
        char szFileName[MAX_PATH];
        HINSTANCE hInstance=GetModuleHandle(NULL);
 
        GetModuleFileName(hInstance, szFileName, MAX_PATH);
        MessageBox(hwnd, "窗口弹出成功", "新消息", MB_OK|MB_ICONINFORMATION);
    }
    break;
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}


在程序中加入这样一段代码之后,在程序窗口中点击一下,便会弹出一个新的窗口。具体效果如下图所示:




深入研究WndProc函数:


    WinProc是窗口回调过程。Windows通过它将事件传递给程序。回调函数是被调用回来的函数。这个函数处理所有发送给主程序窗口的消息。所以,通常WinProc是主程序源代码文件中最长的函数。


    需要了解这个函数,因为它是通向初始化Direct3D的钥匙。它的参数既简单又直白,它们代表Windows程序的真实“引擎”。据前述,这一信息是早先在WinMain中由GetMessage函数获取的。不要将InitInstance和WinProc混淆在一起。InitInstance只运行一次,对选项进行设置。而后就由WinProc接管,接收并处理消息。


有关于WinProc的参数:


HWND hWnd:在游戏中,通常要使用hWnd作为参数创建一个新的设备环境句柄,也就是一个hDC。在DirectX到来之前,必须要保留好窗口句柄,因为只要引用一个窗口或控件就必须使用到它。在DirectX程序中,窗口句柄仅在开始时用于创建窗口。


UINT messgae:发送给窗口回调过程的消息。消息可以是任何东西,甚至是无需使用的消息。由于这个原因,有一个将消息传递给默认消息处理器的方法。


WPARAM wParam和LPARAM lParam:与特定命令消息一起传递过来的参数值的高位和低位。



关于按键消息捕捉的参数:


MK_CONTROL:键盘上Ctrl键被按下;


MK_LBUTTON:鼠标左键被按下;


MK_MBUTTON:鼠标中键被按下;


MK_RBUTTON:鼠标右键被按下;


MK_SHIFT:键盘Shift键被按下;


...其他跟此类似


从头创建windows窗口程序:


  1、创建窗口类;


  2、注册窗口类;


  3、创建窗口; 


  4、显示窗口; 


  5、刷新窗口; 


  6、消息循环; 


   6.1、获取消息; 

   6.2、翻译消息;  

   6.3、分发消息;  


  7、消息处理函数处理消息。


#include <windows.h>
 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("HelloWin") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
 
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
 
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName,                  // window class name
                          TEXT ("The Hello Program"), // window caption
                          WS_OVERLAPPEDWINDOW,        // window style
                          CW_USEDEFAULT,              // initial x position
                          CW_USEDEFAULT,              // initial y position
                          CW_USEDEFAULT,              // initial x size
                          CW_USEDEFAULT,              // initial y size
                          NULL,                       // parent window handle
                          NULL,                       // window menu handle
                          hInstance,                  // program instance handle
                          NULL) ;                     // creation parameters
     
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}
 
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rect ;
     
     switch (message)
     {
     case WM_CREATE:
          PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
          return 0 ;
          
     case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;
          
          GetClientRect (hwnd, &rect) ;
          
          DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
          
          EndPaint (hwnd, &ps) ;
          return 0 ;
          
     case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

窗口类:

typedef struct tagWNDCLASS {
  UINT      style;//窗口风格
  WNDPROC   lpfnWndProc;//窗口消息处理函数
  int       cbClsExtra;//窗口类结构体后面额外分配的内存空间字节数,系统初始化为0
  int       cbWndExtra;//窗口实例后额外分配的内存空间自己数,系统初始化为0,
  HINSTANCE hInstance; //应用程序实例句柄
  HICON     hIcon;//程序图标
  HCURSOR   hCursor; //程序光标
  HBRUSH    hbrBackground; //客户区背景刷颜色
  LPCTSTR   lpszMenuName; //菜单
  LPCTSTR   lpszClassName; //类名
} WNDCLASS, *PWNDCLASS;


 创建窗口函数:

HWND WINAPI CreateWindow(
  _In_opt_ LPCTSTR   lpClassName, //窗口类名称
  _In_opt_ LPCTSTR   lpWindowName, //窗口名称
  _In_     DWORD     dwStyle, //窗口风格
  _In_     int       x,//窗口x坐标
  _In_     int       y,     //窗口y坐标
  _In_     int       nWidth,//窗口宽
  _In_     int       nHeight,//窗口高
  _In_opt_ HWND      hWndParent, //父窗口句柄,没有设为NULL(即父窗口为桌面窗口)
  _In_opt_ HMENU     hMenu,//窗口菜单句柄
  _In_opt_ HINSTANCE hInstance,//窗口实例句柄
  _In_opt_ LPVOID    lpParam//创建窗口时传给WM_CREATE消息的参数
);

好文章,来自【福优学苑@音视频+流媒体】
***【在线视频教程】***