您的位置:首页 > 其它

不使用资源文件动态创建对话框的做法

2014-06-03 15:08 477 查看
作者:朱金灿

一般而言,在 Windows编程中创建对话框需要先定义一个对话框资源。我想能不能不用资源文件单纯通过代码创建对话框呢?晚上搜索了一些资料,研究了一下,基本实现了。



我写了一个KDialog,代码如下(代码中有一些注释,相信大家能基本看懂):

头文件的代码:

[cpp] view
plaincopy

<span style="font-size:16px;">// kdialog.h

#ifndef KDIALOG_H_INCLUDED

#define KDIALOG_H_INCLUDED



#define ID_HELP 150

#define ID_EDIT 180

#define ID_TEXT 200



class KDialog

{

public:



KDialog(HINSTANCE hinst, HWND hwndOwner);



~KDialog();



virtual INT_PTR DoModal();



protected:



// API中注册的消息处理函数,不能是成员函数,因为成员函数有this指针

static BOOL CALLBACK DialogProc(HWND hWnd,

UINT uMsg, WPARAM wParam, LPARAM lParam);



private:



HWND m_hOwnerWnd;



HINSTANCE m_hInst;



};







#endif // KDIALOG_H_INCLUDED

</span>



Cpp文件的代码:



[cpp] view
plaincopy

<span style="font-size:16px;">#include "kdialog.h"



#include "resource.h"



BOOL CALLBACK DialogProc (HWND, UINT, WPARAM, LPARAM) ;



LPWORD lpwAlign ( LPWORD lpIn)

{

ULONG ul;



ul = (ULONG) lpIn;

ul +=3;

ul >>=2;

ul <<=2;

return (LPWORD) ul;

}



KDialog::KDialog(HINSTANCE hinst, HWND hwndOwner)

{

m_hInst = hinst;

m_hOwnerWnd = hwndOwner;

}



KDialog::~KDialog()

{



}



char nEditTwo[128]= "从这儿输入字符串." ;



BOOL CALLBACK KDialog::DialogProc(HWND hDlg,

UINT uMsg, WPARAM wParam, LPARAM lParam)

{

switch (uMsg)

{

case WM_INITDIALOG :

SetDlgItemText ( hDlg, ID_EDIT, nEditTwo );

return TRUE ;



case WM_COMMAND :

switch (LOWORD (wParam))

{

case ID_EDIT :

GetDlgItemText (hDlg, ID_EDIT, nEditTwo, 127);

return TRUE;

case ID_HELP :

MessageBox( NULL, nEditTwo, "输入数据", MB_OK | MB_SYSTEMMODAL | MB_NOFOCUS);

return TRUE;

case IDOK :

EndDialog (hDlg, 0) ;

return TRUE ;

}

break ;

case WM_CLOSE:

EndDialog (hDlg, 0) ;

return TRUE ;

default:

break;

}

return FALSE ;

}



INT_PTR KDialog::DoModal()

{

HGLOBAL hgbl;

LPDLGTEMPLATE lpdt;

LPDLGITEMTEMPLATE lpdit;

LPWORD lpw;

LPWSTR lpwsz;

LRESULT ret;

int nchar;



hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);

if (!hgbl)

return -1;



lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);



// Define a dialog box.



lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU

| DS_MODALFRAME | WS_CAPTION;

lpdt->cdit = 3; // number of controls

lpdt->x = 10;

lpdt->y = 10;

lpdt->cx = 100;

lpdt->cy = 70;



lpw = (LPWORD) (lpdt + 1);

*lpw++ = 0; // no menu

*lpw++ = 0; // predefined dialog box class (by default)



lpwsz = (LPWSTR) lpw;

nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "内存对话框", -1,

lpwsz, 50);

lpw += nchar;



//-----------------------

// Define an OK button.

//-----------------------

lpw = lpwAlign (lpw);



lpdit = (LPDLGITEMTEMPLATE) lpw;

lpdit->x = 10;

lpdit->y = 50;

lpdit->cx = 80;

lpdit->cy = 15;

lpdit->id = IDOK; // OK button identifier

lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;



lpw = (LPWORD) (lpdit + 1);

*lpw++ = 0xFFFF;

*lpw++ = 0x0080; // button class



lpwsz = (LPWSTR) lpw;

nchar = 1+MultiByteToWideChar (CP_ACP, 0, "退出", -1, lpwsz, 50);

lpw += nchar;

*lpw++ = 0; // no creation data





//-----------------------

// Define a Help button.

//-----------------------

lpw = lpwAlign (lpw);



lpdit = (LPDLGITEMTEMPLATE) lpw;

lpdit->x = 10;

lpdit->y = 30;

lpdit->cx = 80;

lpdit->cy = 15;

lpdit->id = ID_HELP; // Help button identifier

lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;



lpw = (LPWORD) (lpdit + 1);

*lpw++ = 0xFFFF;

*lpw++ = 0x0080; // button class atom



lpwsz = (LPWSTR) lpw;

nchar = 1+MultiByteToWideChar (CP_ACP, 0, "显示输入", -1, lpwsz, 50);

lpw += nchar;

*lpw++ = 0; // no creation data





//-----------------------

// Define a EDIT.

//-----------------------

lpw = lpwAlign (lpw);



lpdit = (LPDLGITEMTEMPLATE) lpw;

lpdit->x = 10;

lpdit->y = 10;

lpdit->cx = 80;

lpdit->cy = 12;

lpdit->id = ID_EDIT; // Help button identifier

lpdit->style = ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;



lpw = (LPWORD) (lpdit + 1);

*lpw++ = 0xFFFF;

*lpw++ = 0x0081; // edit class atom

*lpw++ = 0; // no creation data



GlobalUnlock(hgbl);



ret = DialogBoxIndirect(m_hInst,

(LPDLGTEMPLATE) hgbl,

m_hOwnerWnd,

(DLGPROC) DialogProc);



GlobalFree(hgbl);

return ret;

}

</span>



外部调用的方法也很简单(把应用程序句柄和对话框的所有者窗口句柄传进来即可):


[cpp] view
plaincopy

<span style="font-size:16px;"> KDialog dlg(m_hInst,m_hWnd);

dlg.DoModal();

</span>

上面创建的是模式对话框,下面是创建非模式对话框的代码:

[cpp] view
plaincopy

BOOL KDialog::DoModeless()

{

HGLOBAL hgbl;

LPDLGTEMPLATE lpdt;

LPDLGITEMTEMPLATE lpdit;

LPWORD lpw;

LPWSTR lpwsz;

LRESULT ret;

int nchar;



hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);

if (!hgbl)

return FALSE;



lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);



// Define a dialog box.



lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU

| DS_MODALFRAME | WS_CAPTION;

lpdt->cdit = 3; // number of controls

lpdt->x = 10;

lpdt->y = 10;

lpdt->cx = 100;

lpdt->cy = 70;



lpw = (LPWORD) (lpdt + 1);

*lpw++ = 0; // no menu

*lpw++ = 0; // predefined dialog box class (by default)



lpwsz = (LPWSTR) lpw;

nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "内存对话框", -1,

lpwsz, 50);

lpw += nchar;



//-----------------------

// Define an OK button.

//-----------------------

lpw = lpwAlign (lpw);



lpdit = (LPDLGITEMTEMPLATE) lpw;

lpdit->x = 10;

lpdit->y = 50;

lpdit->cx = 80;

lpdit->cy = 15;

lpdit->id = IDOK; // OK button identifier

lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;



lpw = (LPWORD) (lpdit + 1);

*lpw++ = 0xFFFF;

*lpw++ = 0x0080; // button class



lpwsz = (LPWSTR) lpw;

nchar = 1+MultiByteToWideChar (CP_ACP, 0, "退出", -1, lpwsz, 50);

lpw += nchar;

*lpw++ = 0; // no creation data





//-----------------------

// Define a Help button.

//-----------------------

lpw = lpwAlign (lpw);



lpdit = (LPDLGITEMTEMPLATE) lpw;

lpdit->x = 10;

lpdit->y = 30;

lpdit->cx = 80;

lpdit->cy = 15;

lpdit->id = ID_HELP; // Help button identifier

lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;



lpw = (LPWORD) (lpdit + 1);

*lpw++ = 0xFFFF;

*lpw++ = 0x0080; // button class atom



lpwsz = (LPWSTR) lpw;

nchar = 1+MultiByteToWideChar (CP_ACP, 0, "显示输入", -1, lpwsz, 50);

lpw += nchar;

*lpw++ = 0; // no creation data





//-----------------------

// Define a EDIT.

//-----------------------

lpw = lpwAlign (lpw);



lpdit = (LPDLGITEMTEMPLATE) lpw;

lpdit->x = 10;

lpdit->y = 10;

lpdit->cx = 80;

lpdit->cy = 12;

lpdit->id = ID_EDIT; // Help button identifier

lpdit->style = ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;



lpw = (LPWORD) (lpdit + 1);

*lpw++ = 0xFFFF;

*lpw++ = 0x0081; // edit class atom

*lpw++ = 0; // no creation data



GlobalUnlock(hgbl);



HWND hDlg = CreateDialogIndirect(m_hInst,

(LPDLGTEMPLATE) hgbl,

m_hOwnerWnd,

(DLGPROC) DialogProc);

if(NULL==hDlg)

return FALSE;



::ShowWindow(hDlg,SW_SHOW);



GlobalFree(hgbl);

return TRUE;

}

效果图如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: