📄 dialog.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:对话框管理
版本号:2.0.0
开发时期:2000
作者:李林
修改记录:
2004-08-27, 去掉 AP_XSTART, AP_YSTART, AP_WIDTH, AP_HEIGHT,改用系统配置
2003-10-07: LN,对模式对话框清除所有的消息
2003-08-29:LN,增加对 hWnd被DestroyWindow的问题
2003-08-26: LN,增加对 Window Title Ptr 和 lpClasName的映射(MapPtrToProcess)
2003-05-22: LN,对 DS_CENTER 考虑 AP_XSTART, AP_YSTART, AP_WIDTH, AP_HEIGHT
2003-04-10: LN,当处理WM_INITDIALOG是无法设置焦点
(1)增加DoActive 和 hCurCtl去保存Dialog的当前焦点
******************************************************/
#include <eframe.h>
#include <eassert.h>
#include <edialog.h>
//#include <eapisrv.h>
//#include <winsrv.h>
//#include <gdisrv.h>
//#include <epwin.h>
//#include <eobjcall.h>
//#define _MAPPOINTER
static int _RunModalLoop( HWND hWnd );
static BOOL _EnableModal( HWND hWnd );
static HWND _PreModal( HWND );
static LRESULT CALLBACK DialogWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
static const char classDIALOG[] = "DIALOG";
//#define DWL_MSGRESULT 0
//#define DWL_DLGPROC 4
//#define DWL_USER 8
//对话框私有数据结构
typedef struct {
DWORD iResult;
DLGPROC lpDialogFunc;
DWORD dwUserData;
DWORD dwState;
HWND hCurCtl; //LN:2003-04-10
}DLG_WNDEX;
//#define DWL_MSGRESULT 0
//#define DWL_DLGPROC 4
//#define DWL_USER 8
#define DWL_STATE 12
#define DWL_CURCTL 16
#define BUTTON_HEIGHT 20
// **************************************************
// 声明:ATOM RegisterDialogClass( HINSTANCE hInst )
// 参数:
// IN hInst - 实例句柄
// 返回值:
// 假入成功,返回注册的类原子;否则,返回0
// 功能描述:
// 注册对话框类
// 引用:
// 当系统初始化系统类时,会调用该函数
// ************************************************
ATOM RegisterDialogClass( HINSTANCE hInst )
{
WNDCLASS wc;
//初始化类结构
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = DialogWndProc;
wc.hInstance = hInst;
wc.hIcon = NULL;//LoadIcon( NULL, IDI_APPLICATION );
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof( DLG_WNDEX );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = NULL;//GetStockObject( LTGRAY_BRUSH );
wc.lpszMenuName = 0;
wc.lpszClassName = classDIALOG;
//注册
return RegisterClass( &wc );
}
// **************************************************
// 声明:static HWND DoCreateDialog(
// HINSTANCE hInst,
// LPCDLG_TEMPLATE lpcdt,
// HWND hParent,
// DLGPROC lpDialogFunc,
// LPARAM lParamInit,
// BOOL * lpbVisible,
// HANDLE hCallerProcess )
// 参数:
// IN hInst - 实例句柄
// IN lpcdt - 对话框模板结构
// IN hParent - 对话框的父窗口
// IN lpDialogFunc - 对话框回调函数
// IN lParamInit - 传递给 WM_INITDIALOG 消息的LPARAM参数
// OUT lpbVisible - 用于接受是否可视
// IN hCallerProcess - 呼叫该功能的进程
// 返回值:
// 假入成功,返回创建的窗口句柄;否则,返回 NULL
// 功能描述:
// 创建并初始化对话框窗口
// 引用:
//
// ************************************************
static HWND DoCreateDialog( HINSTANCE hInst,
LPCDLG_TEMPLATE lpcdt,
HWND hParent,
DLGPROC lpDialogFunc,
LPARAM lParamInit,
BOOL * lpbVisible,
HANDLE hCallerProcess )
{
HWND hWnd, hChild;
LPCDLG_ITEMTEMPLATE lpcdi = (LPCDLG_ITEMTEMPLATE)(lpcdt + 1);
int i, x, y;
BOOL bVisible;
const char * lpClassName;
*lpbVisible = FALSE;
//假如可能,映射指针
if( lpcdt->lpcClassName )
{
#ifdef _MAPPOINTER
lpClassName = (const char *)MapPtrToProcess( (LPVOID)lpcdt->lpcClassName, hCallerProcess );
#else
lpClassName = (const char *)lpcdt->lpcClassName;
#endif
}
else
lpClassName = classDIALOG;
bVisible = (lpcdt->dwStyle & WS_VISIBLE) ? 1 : 0;
x = lpcdt->x; y = lpcdt->y;
if( lpcdt->dwStyle & DS_CENTER )
{ //对话框需要居中
RECT rect;
if( hParent && (lpcdt->dwStyle & WS_CHILD) )
{ //得到父的客户区矩形
GetClientRect( hParent, &rect );
}
else
{
rect.left = GetSystemMetrics( SM_XCENTER );//AP_XSTART;
rect.top = GetSystemMetrics( SM_YCENTER );//AP_YSTART;
rect.right = rect.left + GetSystemMetrics( SM_CXCENTER );//AP_WIDTH;
rect.bottom = rect.top + GetSystemMetrics( SM_CYCENTER );//AP_HEIGHT;
}
x = ( (rect.right-rect.left) - lpcdt->cx ) / 2 + rect.left;
y = ( (rect.bottom-rect.top) - lpcdt->cy ) / 2 + rect.top;
}
//创建对话框窗口
hWnd = CreateWindowEx( 0,
(LPCBYTE)lpClassName,
#ifdef _MAPPOINTER
MapPtrToProcess( (LPVOID)lpcdt->lpcWindowName, hCallerProcess ),
#else
lpcdt->lpcWindowName,
#endif
lpcdt->dwStyle & (~WS_VISIBLE),
x,
y,
lpcdt->cx,
lpcdt->cy,
hParent,
(HMENU)lpcdt->id,
hInst,
(LPVOID)lpDialogFunc );
if( hWnd )
{ //创建主窗口成功
i = lpcdt->cdit;
//创建子窗口
while( i )
{
hChild = CreateWindowEx(
0,
#ifdef _MAPPOINTER
MapPtrToProcess( (LPVOID)lpcdi->lpcClassName, hCallerProcess ),
MapPtrToProcess( (LPVOID)lpcdi->lpcWindowName, hCallerProcess ),
#else
lpcdi->lpcClassName,
lpcdi->lpcWindowName,
#endif
lpcdi->dwStyle|WS_CHILD,
lpcdi->x,
lpcdi->y,
lpcdi->cx,
lpcdi->cy,
hWnd,
(HMENU)lpcdi->id,
hInst,
lpcdi->lpParam );
if( hChild == NULL )
{ //其中一个子窗口失败
DestroyWindow( hWnd );
hWnd = NULL;
break;
}
i--;
lpcdi++;
}
*lpbVisible = bVisible;
}
return hWnd;
}
// **************************************************
// 声明:static HWND DoCreateIndirectParam(
// HINSTANCE hInst,
// LPCDLG_TEMPLATE lpcdt,
// HWND hParent,
// DLGPROC lpDialogFunc,
// LPARAM lParamInit,
// HANDLE hCallerProcess )
// 参数:
// IN hInst - 实例句柄
// IN lpcdt - 对话框模板结构
// IN hParent - 对话框的父窗口
// IN lpDialogFunc - 对话框回调函数
// IN lParamInit - 传递给 WM_INITDIALOG 消息的LPARAM参数
// IN hCallerProcess - 呼叫该功能的进程
// 返回值:
// 假入成功,返回创建的窗口句柄;否则,返回 NULL
// 功能描述:
// 创建并初始化对话框窗口
// 引用:
//
// ************************************************
static HWND DoCreateIndirectParam(
HINSTANCE hInst,
LPCDLG_TEMPLATE lpcdt,
HWND hParent,
DLGPROC lpDialogFunc,
LPARAM lParamInit,
HANDLE hCallerProcess )
{
BOOL bVisible;
//创建窗口
HWND hWnd = DoCreateDialog( hInst, lpcdt, hParent, lpDialogFunc, lParamInit, &bVisible, hCallerProcess );
if( hWnd )
{
SendMessage( hWnd, WM_INITDIALOG, 0, lParamInit );
if( bVisible )
{
ShowWindow( hWnd, SW_SHOWNORMAL );
}
}
return hWnd;
}
// **************************************************
// 声明:HWND WINAPI Dlg_CreateIndirectParam(
// HINSTANCE hInst,
// LPCDLG_TEMPLATE lpcdt,
// HWND hParent,
// DLGPROC lpDialogFunc,
// LPARAM lParamInit )
// 参数:
// IN hInst - 实例句柄
// IN lpcdt - 对话框模板结构
// IN hParent - 对话框的父窗口
// IN lpDialogFunc - 对话框回调函数
// IN lParamInit - 传递给 WM_INITDIALOG 消息的LPARAM参数
// 返回值:
// 假入成功,返回创建的窗口句柄;否则,返回 NULL
// 功能描述:
// 创建并初始化对话框窗口
// 引用:
// 系统API
// ************************************************
HWND WINAPI Dlg_CreateIndirectParam( HINSTANCE hInst,
LPCDLG_TEMPLATE lpcdt,
HWND hParent,
DLGPROC lpDialogFunc,
LPARAM lParamInit )
{
return DoCreateIndirectParam( hInst, lpcdt, hParent, lpDialogFunc, lParamInit, GetCallerProcess() );
}
// **************************************************
// 声明:HWND WINAPI Dlg_CreateIndirect(
// HINSTANCE hInst,
// LPCDLG_TEMPLATE lpcdt,
// HWND hParent,
// DLGPROC lpDialogFunc )
// 参数:
// IN hInst - 实例句柄
// IN lpcdt - 对话框模板结构
// IN hParent - 对话框的父窗口
// IN lpDialogFunc - 对话框回调函数
// 返回值:
// 假入成功,返回创建的窗口句柄;否则,返回 NULL
// 功能描述:
// 不带参数创建并初始化对话框窗口
// 引用:
// 系统API
// ************************************************
HWND WINAPI Dlg_CreateIndirect( HINSTANCE hInst, LPCDLG_TEMPLATE lpcdt, HWND hParent, DLGPROC lpDialogFunc )
{
return DoCreateIndirectParam( hInst, lpcdt, hParent, lpDialogFunc, 0, GetCallerProcess() );
}
// **************************************************
// 声明:static LRESULT DoDialogModal( HWND hWnd, HWND hWndParent, LPARAM lParamInit, BOOL bVisible )
// 参数:
// IN hWnd - 窗口句柄
// IN hWndParent - 父窗口
// IN lParamInit - 传递给 WM_INITDIALOG 消息的LPARAM参数
// IN bVisible
// 返回值:
// 返回结果值
// 功能描述:
// 处理模式对话框
// 引用:
//
// ************************************************
#define DEBUG_DO_DIALOG_MODAL 0
static LRESULT DoDialogModal( HWND hWnd, HWND hWndParent, LPARAM lParamInit, BOOL bVisible )
{
HWND hwndTop;
BOOL bEnable = FALSE;
DEBUGMSG( DEBUG_DO_DIALOG_MODAL, ( "DoDialogModal:Enter.\r\n" ) );
if( bVisible )
ShowWindow( hWnd, SW_SHOWNORMAL );
SendMessage( hWnd, WM_INITDIALOG, 0, lParamInit );
if( bVisible && _EnableModal( hWnd ) )
{
if( (GetWindowLong( hWnd, GWL_STYLE ) & WS_CHILD) == 0 )
SetForegroundWindow( hWnd );
}
//是否退出 ?
if( _EnableModal( hWnd ) )
{ //否
//搜索顶级窗口
hwndTop = _PreModal( hWndParent );
if( hwndTop && IsWindowEnabled( hwndTop ) )
{ //无效顶级窗口
EnableWindow( hwndTop, FALSE );
bEnable = TRUE;
}
DEBUGMSG( DEBUG_DO_DIALOG_MODAL, ( "DoDialogModal:_RunModalLoop Enter.\r\n" ) );
_RunModalLoop( hWnd );
DEBUGMSG( DEBUG_DO_DIALOG_MODAL, ( "DoDialogModal:_RunModalLoop Leave.\r\n" ) );
//隐藏窗口
ShowWindow( hWnd, SW_HIDE );
if( bEnable )
{
EnableWindow( hwndTop, TRUE );
}
if( hwndTop && GetActiveWindow() == hWnd )
SetActiveWindow( hwndTop ); //恢复之前的状态
}
//返回结果值
return (int)GetWindowLong( hWnd, DWL_MSGRESULT );
}
// **************************************************
// 声明:static int DoBoxIndirectParam(
// HANDLE hInst,
// LPDLG_TEMPLATE lpTemplate,
// HWND hWndParent,
// DLGPROC lpDialogFunc,
// LPARAM lParamInit,
// HANDLE hCallerProcess )
// 参数:
// IN hInst - 实例句柄
// IN lpTemplate - 对话框模板结构
// IN hWndParent - 对话框的父窗口
// IN lpDialogFunc - 对话框回调函数
// IN lParamInit - 传递给 WM_INITDIALOG 消息的LPARAM参数
// IN hCallerProcess - 呼叫者进程
// 返回值:
// 假入成功,返回处理结果;否则,返回 -1
// 功能描述:
// 创建并初始化对话框窗口,并进入模式处理过程
// 引用:
// 系统API
// ************************************************
static int DoBoxIndirectParam( HANDLE hInst, LPDLG_TEMPLATE lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM lParamInit, HANDLE hCallerProcess )
{
HWND hWnd;//, hwndTop;
BOOL bEnable = FALSE;
int result = -1;
BOOL bVisible;
MSG msg;
//清除所有的鼠标消息
//ClearThreadQueue( 0, NULL, WM_MOUSEFIRST,WM_MOUSELAST );
while( PeekMessage( &msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) )
;
//清除所有的键盘消息
//ClearThreadQueue( 0, NULL, WM_KEYFIRST,WM_KEYLAST );
while( PeekMessage( &msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) )
;
//创建对话框
hWnd = DoCreateDialog( hInst, lpTemplate, hWndParent, lpDialogFunc, lParamInit, &bVisible, hCallerProcess );
if( hWnd )
{ //处理模式过程
result = DoDialogModal( hWnd, hWndParent, lParamInit, bVisible );
//破坏窗口
DestroyWindow( hWnd );
}
return result;
}
// **************************************************
// 声明:int WINAPI Dlg_BoxIndirectParam(
// HANDLE hInst,
// LPDLG_TEMPLATE lpTemplate,
// HWND hWndParent,
// DLGPROC lpDialogFunc,
// LPARAM lParamInit )
// 参数:
// IN hInst - 实例句柄
// IN lpTemplate - 对话框模板结构
// IN hWndParent - 对话框的父窗口
// IN lpDialogFunc - 对话框回调函数
// IN lParamInit - 传递给 WM_INITDIALOG 消息的LPARAM参数
// 返回值:
// 假入成功,返回处理结果;否则,返回 -1
// 功能描述:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -