创建一个简单的属性页对话框(1)

要创建一个属性页的对话框,必须先自己定义几个属性页,如:


IDD_SHEET01 DIALOGEX 0, 0, 186, 93
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    CONTROL         "属性页一",IDC_ONE_TEST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,35,103,12
END

IDD_SHEET02 DIALOGEX 0, 0, 186, 93
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    CONTROL         "属性页二",IDC_TWO_TEST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,38,35,122,15
END

这里为了示例方便,只简单的定义了两个属性页.然后就需要要创建属性页对话框前先填充一个结构,PROPSHEETPAGE,结构定义如下:


typedef struct _PROPSHEETPAGE {
    DWORD dwSize;    //指定结构的大小
    DWORD dwFlags;    //标志位,表明创建属性页时使用到的选项
    HINSTANCE hInstance;
    union {
        LPCSTR pszTemplate;  //指定属性页的模板(对话框资源)
        LPCDLGTEMPLATE pResource;
        };
    union {
        HICON hIcon;
        LPCSTR pszIcon;
        };
    LPCSTR pszTitle;
    DLGPROC pfnDlgProc;  //指向对话框模板的回调函数
      //但是需要注意的是,不能在这个回调函数里调用EndDialog()函数
    LPARAM lParam;
    LPFNPSPCALLBACK pfnCallback;//指向用户定义的回调函数,原型是:
        //UINT CALLBACK PropSheetPageProc(HWND,UINT,LPPROPSHEETPAGE);
        //用户处理页面建立时的初始设置与结束时的清理工作
    UINT *pcRefParent;
#if (_WIN32_IE >= 0x0500)
    LPCTSTR pszHeaderTitle;
    LPCTSTR pszHeaderSubTitle;
#endif
#if (_WIN32_WINNT >= 0x0501)
    HANDLE hActCtx;
#endif
} PROPSHEETPAGE, *LPPROPSHEETPAGE;

对于dwFlags成员,常用的标志有: PSP_USEICONID | PSP_USETITLE
PSP_USEICONID  //在标签上显示图标
PSP_USETITLE  //在标签上显示标签名,在接下来,我们可以通过设定pszTitle成员来指定
如这个示例里的设定:


  g_hInst=hInstance;
  PROPSHEETPAGE psp[2];
    psp[0].dwSize = sizeof(PROPSHEETPAGE);
    psp[0].dwFlags = PSP_USEICONID | PSP_USETITLE | PSP_HIDEHEADER;
    psp[0].hInstance = g_hInst;
    psp[0].pszTemplate = MAKEINTRESOURCE(IDD_SHEET01);
    psp[0].pszIcon = 0;
    psp[0].pfnDlgProc = SheetOneProc;
    psp[0].pszTitle = TEXT("Sheet01");
    psp[0].lParam = 0;
    psp[0].pfnCallback = NULL;

    psp[1].dwSize = sizeof(PROPSHEETPAGE);
    psp[1].dwFlags = PSP_USEICONID | PSP_USETITLE | PSP_HIDEHEADER;
    psp[1].hInstance = g_hInst;
    psp[1].pszTemplate = MAKEINTRESOURCE(IDD_SHEET02);
    psp[1].pszIcon =0;
    psp[1].pfnDlgProc = SheetTwoProc;
    psp[1].pszTitle = TEXT("Sheet02");
    psp[1].lParam = 0;
    psp[1].pfnCallback = NULL;

接下来,就是把这些定义的属性页绑定到属性对话框上了,这样,我们就必须指定一个PROPSHEETHEADER结构,该结构定义如下:


typedef struct _PROPSHEETHEADER
{
    DWORD dwSize;
    DWORD dwFlags;
    HWND  hwndParent;
    HINSTANCE hInstance;
    union {
        HICON hIcon;
        LPCTSTR pszIcon;
        };
    LPCTSTR pszCaption;
    UINT nPages;
    union {
        UINT nStartPage;
        LPCTSTR pStartPage;
        };
    union {
        LPCPROPSHEETPAGE ppsp;
        HPROPSHEETPAGE *phpage;
        };
    PFNPROPSHEETCALLBACK pfnCallback;
#if (_WIN32_IE >= 0x0400)
    union {
        HBITMAP hbmWatermark;
        LPCTSTR pszbmWatermark;
        };
    HPALETTE hplWatermark;
    union {
        HBITMAP hbmHeader;
        LPCSTR pszbmHeader;
        };
#endif
} PROPSHEETHEADER, *LPPROPSHEETHEADER;

这个结构里,我们需要注意的有:
dwFlags    //常用的标志有 PSH_USEICONID | PSH_PROPSHEETPAGE | PSH_USECALLBACK;
    //如果是向导模式,则需加上PSH_WIZARD或者PSH_WIZARD97
nPages    //属性页的页面数
psh.pszCaption  //设定主窗口的标题
…………
这里填充如下:


  PROPSHEETHEADER psh;
    psh.dwSize = sizeof(PROPSHEETHEADER);
    psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE | PSH_USECALLBACK;
    psh.hwndParent = 0;
    psh.hInstance = g_hInst;
    psh.pszIcon = MAKEINTRESOURCE(IDI_MAIN);
    psh.pszCaption = (LPSTR) "Properties Sheet Test";
    psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
    psh.nStartPage = 0;
    psh.ppsp = (LPCPROPSHEETPAGE) &psp;
    psh.pfnCallback = NULL;

接下来就是调用PropertySheet()函数了,以PROPSHEETHEADER结构为唯一参数:


PropertySheet(&psh);

好了,下面就是写各自页面的对应回调函数了:


INT_PTR CALLBACK SheetOneProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
  switch(uMsg){
    case WM_INITDIALOG:
      return TRUE;
    case WM_COMMAND:
      /*switch(LOWORD(wParam)){
        case IDCANCEL:
          EndDialog(hDlg,0);
          return TRUE;
      }*/
      return TRUE;
  }
  return FALSE;
}

INT_PTR CALLBACK SheetTwoProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
  switch(uMsg){
    case WM_INITDIALOG:
      return TRUE;
    case WM_COMMAND:
      /*switch(LOWORD(wParam)){
        case IDCANCEL:
          EndDialog(hDlg,0);
          return TRUE;
      }*/
      return TRUE;
  }
  return FALSE;
}

一个简单的属性页对话框或者向导对话框就这样OK了,完整的代码如下:


#include
#include
#include"resource.h"

#pragma comment(lib,"comctl32.lib")

HINSTANCE g_hInst;
INT_PTR CALLBACK SheetOneProc(HWND,UINT,WPARAM,LPARAM);
INT_PTR CALLBACK SheetTwoProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lpCmdLine,int nShowCmd){
  g_hInst=hInstance;
  PROPSHEETPAGE psp[2];
    psp[0].dwSize = sizeof(PROPSHEETPAGE);
    psp[0].dwFlags = PSP_USEICONID | PSP_USETITLE | PSP_HIDEHEADER;
    psp[0].hInstance = g_hInst;
    psp[0].pszTemplate = MAKEINTRESOURCE(IDD_SHEET01);
    psp[0].pszIcon = 0;
    psp[0].pfnDlgProc = SheetOneProc;
    psp[0].pszTitle = TEXT("Sheet01");
    psp[0].lParam = 0;
    psp[0].pfnCallback = NULL;

    psp[1].dwSize = sizeof(PROPSHEETPAGE);
    psp[1].dwFlags = PSP_USEICONID | PSP_USETITLE | PSP_HIDEHEADER;
    psp[1].hInstance = g_hInst;
    psp[1].pszTemplate = MAKEINTRESOURCE(IDD_SHEET02);
    psp[1].pszIcon =0;
    psp[1].pfnDlgProc = SheetTwoProc;
    psp[1].pszTitle = TEXT("Sheet02");
    psp[1].lParam = 0;
    psp[1].pfnCallback = NULL;

  PROPSHEETHEADER psh;
    psh.dwSize = sizeof(PROPSHEETHEADER);
    psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE | PSH_USECALLBACK;
    psh.hwndParent = 0;
    psh.hInstance = g_hInst;
    psh.pszIcon = MAKEINTRESOURCE(IDI_MAIN);
    psh.pszCaption = (LPSTR) "Properties Sheet Test";
    psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
    psh.nStartPage = 0;
    psh.ppsp = (LPCPROPSHEETPAGE) &psp;
    psh.pfnCallback = NULL;
    PropertySheet(&psh);

  return 0;
}

INT_PTR CALLBACK SheetOneProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
  switch(uMsg){
    case WM_INITDIALOG:
      return TRUE;
    case WM_COMMAND:
      /*switch(LOWORD(wParam)){
        case IDCANCEL:
          EndDialog(hDlg,0);
          return TRUE;
      }*/
      return TRUE;
  }
  return FALSE;
}

INT_PTR CALLBACK SheetTwoProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
  switch(uMsg){
    case WM_INITDIALOG:
      return TRUE;
    case WM_COMMAND:
      /*switch(LOWORD(wParam)){
        case IDCANCEL:
          EndDialog(hDlg,0);
          return TRUE;
      }*/
      return TRUE;
  }
  return FALSE;
}

“创建一个简单的属性页对话框(1)”的一个回复

发表评论