WIN32创建模态和非模态弹窗框

第一步,在资源文件中创建弹出框资源。

新建两个弹出框资源,菜单分别为IDD_DIALOG1 和IDD_DIALOG2

二、建立一个顶级菜单,方便操作。

ID分别设置为 ID_MODEL(模态) 和 ID_NO_MODEL(非模态)

三、在.cpp中的窗口处理函数的添加WM_COMMAND的后续处理函数

    .......
    case WM_COMMAND: {
        OnCommand(hwnd, wParam);
        break;
   .......
void OnCommand(HWND hwnd,  WPARAM wParam) {
   //点击不同菜单之后做不同的处理。
    switch (LOWORD(wParam))
    {
    case ID_MODEL:{
        DialogBoxA( g_hInstance, (char*)IDD_DIALOG1, hwnd, DlgProc); //创建模态
       break;
    }
    case ID_NO_MODEL: {
       //创建非模态
       HWND hNoModelWnd =  CreateDialog(g_hInstance, (char*)IDD_DIALOG2, hwnd, DlgNoModeProc);
       //显示窗口(模态不需要)
       ShowWindow(hNoModelWnd, SW_SHOW);
       break;
    }
    default:
        break;
    }

}
INT_PTR  DlgProc(HWND hwnd, UINT msgId, WPARAM wParam, LPARAM lParam) {
  
    switch (msgId)
    {
    case WM_SYSCOMMAND:
    {
        //点击关闭弹出窗口的关闭按钮
        if (wParam == SC_CLOSE) {
            EndDialog(hwnd, TRUE); //模态必须要用EndDialog,因为这个函数既可以销毁窗口又能解除阻塞
        }
        break;
    }
    default:
        break;
    }

    return FALSE;
}

//非模态
INT_PTR  DlgNoModeProc(HWND hwnd, UINT msgId, WPARAM wParam, LPARAM lParam) {
    switch (msgId)
    {
    case WM_SYSCOMMAND:
    {
        //点击关闭弹出窗口的关闭按钮
        if (wParam == SC_CLOSE) {
            DestroyWindow(hwnd); //只要销毁窗口,不需要解除窗口,所以不需要用EndDialog
        }
        break;
    }
    default:
        break;
    }

    return FALSE;
}

当我们创建主窗口的时候系统会发送WM_CREATE消息,但是创建弹窗窗口的时候发送的不是WM_CREATE而是发送的WM_INITDIALOG,这是弹窗窗口和其他窗口不同之处,其他的和普通窗口处理没有差异。

WIN32中添加上下文菜单

我们经常看到在界面上点击右键出现一个菜单,这个菜单就是上下文菜单,有些人也把它叫做“右键菜单”。

在win32中我们创建菜单只能创建顶部菜单,那么这种上下文菜单是如何实现的呢,其实就是拿这个顶部菜单的一部分,也就是这个顶部菜单的子菜单。

单我们点击鼠标右键的时候窗口会有产生两个消息分别是“WM_RBUTTONUP” 和 “WM_CONTEXTMENU”。在这里我们用WM_CONTEXTMENU,因为WM_CONTEXTMENU消息附带了以屏幕为准的鼠标的x,y坐标。

WM_CONTEXTMENU中定义一个处理函数OnContentMenu,接收两个参数(HWND hwnd, LPARAM lParam)

VOID OnContentMenu(HWND hwnd, LPARAM lParam) {
	HMENU MainhMenu = LoadMenu(g_hInstance, (char*)IDR_MENU1); //加载顶部菜单
	HMENU hMenu = GetSubMenu(MainhMenu, 0);//获取顶部菜单的子菜单,0是索引。
        //TrackPopupMenu是创建一个上下文菜单。可以参考msdn文档。
	TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_TOPALIGN, LOWORD(lParam), HIWORD(lParam),0,hwnd,NULL);
}

这样就可以在鼠标点击的时候弹出菜单了。点击菜单项之后去 WM_COMMAND 消息处理。

WIN32挂载顶部菜单的三种方式

第一种:在注册窗口类

给lpszMenuName属性赋值: winClass.lpszMenuName = (char*)IDR_MENU1

第二种:在创建窗口的时候赋值参数

在执行CreateWindow的时候,传递菜单句柄。

HMENU hMenu = LoadMenu(hInstance, (char*)IDR_MENU1);
HWND hWnd = CreateWindow(CLASS_NAME, "JishugeApp", WS_OVERLAPPEDWINDOW, 100, 100, 800, 500, NULL, hMenu, hInstance, NULL);

第三种:在WM_CREATE消息挂载菜单

定义一个全局进程句柄:HINSTANCE g_hInstance = NULL;

在入口函数给全局句柄赋值 : g_hInstance = hInstance;

在WM_CREATE消息的时候调用自定义函数OnCreate

VOID OnCreate(HWND hwnd) {
	HMENU hMenu = LoadMenu(g_hInstance, (char*)IDR_MENU1);
	SetMenu(hwnd, hMenu);
}

win32窗口常见的消息

WM_CREATE

  • 触发时机:在窗口创建成功但是还没有被显示时
  • 附带信息
    • wParam:0;
    • lParam:为CREATESTRUCT类似的指针,通过这个指针可以获取CreateWindow的全部参数信息
  • 使用场景:一般用于初始化窗口的参数、资源、创建子窗口等等。

WM_DESTROY

  • 触发时机:窗口被销毁的时候。
  • 附带信息
    • wParam:0;
    • lParam:0;
  • 使用场景:一般用于窗口销毁前的处理工作,比如资源、内存等等。

WM_SYSCOMMAND

  • 触发时机:点击窗口的最大化、最小化、关闭等。
  • 附带信息
    • wParam:具体点击的位置,例如关闭SC_CLOSE等;
    • lParam:鼠标光标的位置。
      • LOWORD(lParam); x 坐标
      • HIWORD(lParam); y 坐标
  • 使用场景:一般用于窗口关闭的时候,提示用户处理

WM_QUIT

  • 触发时机:程序员主动触发
  • 附带信息
    • wParam:PostQuitMessage 函数传递的参数;
    • lParam:0;
  • 使用场景:一般用于结束消息循环,当GetMessage收到该消息后,会返回FALSE,来结束while循环,退出循环消息。

WM_SIZE

  • 触发时机:在窗口的大小发生变化的时候
  • 附带信息
    • wParam:窗口大小变化的原因(一般不重要);
    • lParam:窗口变化后的大小;
      • LOWORD(lParam):变化后的宽度
      • HIWORD(lParam):变化后的高度
  • 使用场景:一般用于窗口大小变化后,调整窗口各个部分的布局。

在Win32窗口开发中通过控制台输出方式

一、定义一个全局变量,HANDLE类型

HANDLE g_outPut = 0;

二、启动console输出

在入口函数执行函数 AllocConsole();

三、在入口函数内获取标志输出句柄并赋值给全局变量

g_outPut = GetStdHandle(STD_OUTPUT_HANDLE);

四、输出内容到控制台

WriteConsole(g_outPut , "哈哈",strlen("哈哈"),NULL,NULL);