windows sdk 资源和对话框创建

本文深入探讨了Win32环境下资源的概念与管理,包括资源ID的设定与转换,以及如何在EXE文件中集成资源。同时,详细解析了对话框的创建与处理,区分模态与非模态对话框的不同实现原理与使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

资源

概念

  • 资源:所有除代码以外的东西都可称为资源
  • ID:SDK所有添加的资源都可以设置唯一的ID
    • 若用字符串命名资源ID,需要字符串外加入双引号("")
    • 可用指定API将资源ID转换为对应指针 宏函数MAKEINTRESOURCE(MN_EDIT) // ID转指针

带资源的EXE文件生成流程

WM_COMMAND在窗口菜单程序中使用

// Win32Test.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "Win32Test.h"
#include "resource.h"

void ShowErrorMessage()
{
  LPVOID lpMsgBuf;

  //将错误码转化为错误信息,参数可以抄MSDN
  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR)&lpMsgBuf,
    0,
    NULL
    );
  // Process any inserts in lpMsgBuf.
  // ...
  // 弹出错误提示窗口.
  MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK | MB_ICONINFORMATION);
  // Free the buffer.
  LocalFree(lpMsgBuf);
}


LRESULT CALLBACK MyWindowPro
(HWND hwnd,     // 窗口句柄
UINT uMsg,      // 消息标识
WPARAM wParam,  // 附加在消息上的参数
LPARAM lParam   // 附加在消息上的参数
)
{
  switch (uMsg)
  {  
  case WM_COMMAND:
  {
                   //高位判断通知类型如果来自菜单,则为0, 如果来自快捷键,则为1
                   WORD wFrom = HIWORD(wParam);

                   //低位保存菜单\快捷键的ID
                   WORD wID = LOWORD(wParam);

                   //菜单
                   if (wFrom == 0)
                   {
                     switch (wID)
                     {
                     case IDM_OPEN:
                       MessageBox(hwnd, TEXT("打开菜单"), NULL, MB_OK);
                       break;

                     case IDM_CLSOE:
                       MessageBox(hwnd, TEXT("关闭菜单"), NULL, MB_OK);
                       break;

                     default:
                       break;
                     }
                   }
                   else if (wFrom == 1)
                   {
                     switch (wID)
                     {
                     case IDA_ALT_O:
                       MessageBox(hwnd, TEXT("打开菜单"), NULL, MB_OK);
                       break;

                     case IDA_ALT_C:
                       MessageBox(hwnd, TEXT("关闭菜单"), NULL, MB_OK);
                       break;

                     default:
                       break;
                     }
                   }
                   break;
  }
  //点击关闭窗口会发送WM_CLOSE消息
  case WM_CLOSE:
  {
                 int nRet = MessageBox(hwnd, TEXT("是否退出"), TEXT("询问"), MB_OKCANCEL);
                 if (nRet == IDCANCEL)//取消关闭
                 {
                   return 0;
                 }
                 else
                 {
                   //摧毁窗口发送WM_DESTROY消息
                   DestroyWindow(hwnd);
                 }

                 break;
  }
  case WM_DESTROY:
  {
                   //向消息队列投递WM_QUIT消息 WM_QUIT使消息循环退出,程序退出。
                   PostQuitMessage(0);
                   break;
  }
  default:
    break;
  }
  //系统默认处理消息窗口函数
  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

//句柄可以理解为标识ID,如窗口句柄就表示这个标识这个窗口的唯一ID
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,//应用程序当前实例的句柄
                     _In_opt_ HINSTANCE hPrevInstance,//应用程序的先前实例的句柄
                     _In_ LPTSTR    lpCmdLine,//指向应用程序命令行的字符串的指针
                     _In_ int       nCmdShow)//指明窗口如何显示,查msdn帮助文档,有各种宏
{

  WNDCLASS wc;
  wc.style = CS_HREDRAW | CS_VREDRAW; //默认风格,窗口尺寸被修改后重画窗口
  wc.lpfnWndProc = MyWindowPro; //窗口回调
  wc.cbClsExtra = 0; //窗口类的额外空间 
  wc.cbWndExtra = 0; //窗口实例的额外空间
  wc.hInstance = hInstance;
  wc.hIcon = NULL; //图标
  wc.hCursor = NULL; //光标
  wc.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT);//背景
  wc.lpszMenuName = MAKEINTRESOURCE(IDM_TEST);//菜单
  wc.lpszClassName = TEXT("MyWindow");

  //加载菜单
  HMENU hMenu = LoadMenu(hInstance, TEXT("testmenu"));

  ATOM nRet = RegisterClass(&wc);
  if (nRet == 0)
  {
    ShowErrorMessage();
  }

  //创建窗口实例
  HWND hWnd = CreateWindow(
    TEXT("MyWindow"), //窗口类名
    TEXT("Hello World"), //窗口标题
    WS_OVERLAPPEDWINDOW, //重叠窗口
    CW_USEDEFAULT, CW_USEDEFAULT, //默认坐标
    CW_USEDEFAULT, CW_USEDEFAULT,//默认长和宽
    NULL, //没有父窗口
    NULL, //加载菜单
    hInstance,//main函数的实例句柄
    NULL//暂时不用,(LPVOID)0x87654093,可用来做参数标记
    );
  if (hWnd == NULL)
  {
    ShowErrorMessage();
  }

  //显示窗口
  ShowWindow(hWnd, SW_SHOW);

  //更新窗口
  UpdateWindow(hWnd);


  MSG msg;
  //消息循环
  //加载快捷键
  HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_TEST));
  while (GetMessage(&msg, NULL, 0, 0) != 0)
  {
    //转换WM_KEYDOWN消息为快捷键消息
    if (!TranslateAccelerator(hWnd, hAccel, &msg))
    {
      //将keydown消息转换为字符消息
      TranslateMessage(&msg);

      //派发消息到对应的窗口过程函数
      DispatchMessage(&msg);
    }
  }
  return 0;
}

概念

对话框是一种特殊的视窗,用来在用户界面中向用户显示信息,或者在需要的时候获得用户的输入响应。

对话框三要素

  1. 编辑对话框模板资源(CTRL+T 可预览创建的对话框)
  2. 实现对话框过程函数
  3. 创建对话框示例

非模态对话框和模态对话框

联系

创建时都会发送VM_INITDIALOG消息

区别

  • 创建函数不同
//创建模态对话框
DialogBox(g_hInstance,
  MAKEINTRESOURCE(DLG_TEST),//对话框ID
  hwnd,
  ModDialogProc);//对话框过程函数
  
//创建非模态对话框
CreateDialog(g_hInstance,
  MAKEINTRESOURCE(DLG_TEST),//对话框ID
  hwnd,
  ModDialogProc);//对话框过程函数

  • 销毁函数不同
//销毁模态对话框
EndDialog(hwndDlg, 0);
  
//销毁非模态对话框
DestroyWindow(hwndDlg);

  • 对话框实现原理不同
//模态对话框创建时会调用此函数,禁止父窗口接受鼠标键盘操作
EnableWindow(g_hWnd, false);

//模态对话框销毁时会调用此函数,允许父窗口接受鼠标键盘操作
EnableWindow(g_hWnd, true);
  • 对话框显示方式不同
//非模态对话框创建完,需要调指定函数才可显示
HWND hWnd = CreateDialog(g_hInstance,
  MAKEINTRESOURCE(DLG_TEST),
  hwnd, 
  ModlessDialogProc);

ShowWindow(hWnd, SW_SHOW);

创建对话框代码 

// Win32Test.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "Win32Test.h"
#include "resource.h"

/* 全局变量                                                                     */
/************************************************************************/
HINSTANCE g_hInstance = NULL;
HWND g_hWnd = NULL;

void ShowErrorMessage()
{
  LPVOID lpMsgBuf;

  //将错误码转化为错误信息,参数可以抄MSDN
  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR)&lpMsgBuf,
    0,
    NULL
    );
  // Process any inserts in lpMsgBuf.
  // ...
  // 弹出错误提示窗口.
  MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK | MB_ICONINFORMATION);
  // Free the buffer.
  LocalFree(lpMsgBuf);
}


/************************************************************************/
/* 对话框处理函数                                                                     */
/************************************************************************/
BOOL CALLBACK ModDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
  //  //创建显示对话框之前触发的消息
  //case  WM_INITDIALOG:
  //  //允许父窗口接受鼠标键盘操作
  //  EnableWindow(g_hWnd, TRUE);
  //  break;

  case WM_CLOSE:
    //模态对话框销毁使用EndDialog
    EndDialog(hwndDlg, 0);
    break;

  default:
    break;
  }
  return FALSE;
}

//非模态对话框的处理函数
BOOL CALLBACK ModlessDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
  ////把非模态对话框修为模态对话框
  //case  WM_INITDIALOG:
  //  //允许父窗口接受鼠标键盘操作
  //  EnableWindow(g_hWnd, FALSE);
  //  break;

  case WM_CLOSE:
    //非模态对话框销毁使用DestroyWindow
    DestroyWindow(hwndDlg);

    break;

  default:
    break;
  }
  return FALSE;
}

LRESULT CALLBACK MyWindowPro
(HWND hwnd,     // 窗口句柄
UINT uMsg,      // 消息标识
WPARAM wParam,  // 附加在消息上的参数
LPARAM lParam   // 附加在消息上的参数
)
{
  switch (uMsg)
  {  
  case WM_COMMAND:
  {
                   //高位判断通知类型如果来自菜单,则为0, 如果来自快捷键,则为1
                   WORD wFrom = HIWORD(wParam);

                   //低位保存菜单\快捷键的ID
                   WORD wID = LOWORD(wParam);

                   //菜单
                   if (wFrom == 0)
                   {
                     switch (wID)
                     {
                     case IDM_MODE_DIALOG:
                     {
                                           //创建对话框
                                           DialogBox(g_hInstance,
                                             MAKEINTRESOURCE(IDD_DIALOG1),
                                             hwnd,
                                             ModDialogProc);
                                           break;
                     }
                      

                     case IDM_DIALOG:
                     {
                                      //创建非模态对话框
                                      HWND hWnd = CreateDialog(g_hInstance,
                                        MAKEINTRESOURCE(IDD_DIALOG1),
                                        hwnd,
                                        ModlessDialogProc);

                                      ShowWindow(hWnd, SW_SHOW);
                                      break;
                     }
                       
                     default:
                       break;
                     }
                   }
      
                   break;
  }
  //点击关闭窗口会发送WM_CLOSE消息
  case WM_CLOSE:
  {
                 int nRet = MessageBox(hwnd, TEXT("是否退出"), TEXT("询问"), MB_OKCANCEL);
                 if (nRet == IDCANCEL)//取消关闭
                 {
                   return 0;
                 }
                 else
                 {
                   //摧毁窗口发送WM_DESTROY消息
                   DestroyWindow(hwnd);
                 }

                 break;
  }
  case WM_DESTROY:
  {
                   //向消息队列投递WM_QUIT消息 WM_QUIT使消息循环退出,程序退出。
                   PostQuitMessage(0);
                   break;
  }
  default:
    break;
  }
  //系统默认处理消息窗口函数
  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

//句柄可以理解为标识ID,如窗口句柄就表示这个标识这个窗口的唯一ID
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,//应用程序当前实例的句柄
                     _In_opt_ HINSTANCE hPrevInstance,//应用程序的先前实例的句柄
                     _In_ LPTSTR    lpCmdLine,//指向应用程序命令行的字符串的指针
                     _In_ int       nCmdShow)//指明窗口如何显示,查msdn帮助文档,有各种宏
{

  g_hInstance = hInstance;

  WNDCLASS wc;
  wc.style = CS_HREDRAW | CS_VREDRAW; //默认风格,窗口尺寸被修改后重画窗口
  wc.lpfnWndProc = MyWindowPro; //窗口回调
  wc.cbClsExtra = 0; //窗口类的额外空间 
  wc.cbWndExtra = 0; //窗口实例的额外空间
  wc.hInstance = hInstance;
  wc.hIcon = NULL; //图标
  wc.hCursor = NULL; //光标
  wc.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT);//背景
  wc.lpszMenuName = MAKEINTRESOURCE(IDM_TEST);//菜单
  wc.lpszClassName = TEXT("MyWindow");

  //加载菜单
  HMENU hMenu = LoadMenu(hInstance, TEXT("testmenu"));

  ATOM nRet = RegisterClass(&wc);
  if (nRet == 0)
  {
    ShowErrorMessage();
  }

  //创建窗口实例
  HWND hWnd = CreateWindow(
    TEXT("MyWindow"), //窗口类名
    TEXT("Hello World"), //窗口标题
    WS_OVERLAPPEDWINDOW, //重叠窗口
    CW_USEDEFAULT, CW_USEDEFAULT, //默认坐标
    CW_USEDEFAULT, CW_USEDEFAULT,//默认长和宽
    NULL, //没有父窗口
    NULL, //加载菜单
    hInstance,//main函数的实例句柄
    NULL//暂时不用,(LPVOID)0x87654093,可用来做参数标记
    );
  if (hWnd == NULL)
  {
    ShowErrorMessage();
  }
  g_hWnd = hWnd;
  //显示窗口
  ShowWindow(hWnd, SW_SHOW);

  //更新窗口
  UpdateWindow(hWnd);


  MSG msg;
  //消息循环
  //加载快捷键
  HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_TEST));
  while (GetMessage(&msg, NULL, 0, 0) != 0)
  {
    //转换WM_KEYDOWN消息为快捷键消息
    if (!TranslateAccelerator(hWnd, hAccel, &msg))
    {
      //将keydown消息转换为字符消息
      TranslateMessage(&msg);

      //派发消息到对应的窗口过程函数
      DispatchMessage(&msg);
    }
  }
  return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值