-
Notifications
You must be signed in to change notification settings - Fork 539
/
Dialog.hpp
137 lines (115 loc) · 3.77 KB
/
Dialog.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#pragma once
#include "window.hpp"
/// <summary>
/// Generic dialog class
/// </summary>
class Dialog : public Window
{
public:
typedef INT_PTR( Dialog::*fnDlgProc )(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
typedef std::map<UINT, fnDlgProc> mapMsgProc;
typedef std::map<WORD, fnDlgProc> mapCtrlProc;
public:
Dialog( int dialogID )
: _dialogID( dialogID )
{
_messages[WM_INITDIALOG] = &Dialog::OnInit;
_messages[WM_COMMAND] = &Dialog::OnCommand;
_messages[WM_CLOSE] = &Dialog::OnClose;
}
/// <summary>
/// Run dialog as modal window
/// </summary>
/// <param name="parent">Parent window.</param>
/// <returns>TRUE on success, FALSE otherwise</returns>
virtual INT_PTR RunModal( HWND parent = NULL )
{
// Stupid std::function and std::bind don't support __stdcall
// Had to do this idiotic workaround
Win32Thunk<DLGPROC, Dialog> dlgProc( &Dialog::DlgProc, this );
return DialogBoxW( NULL, MAKEINTRESOURCEW( _dialogID ), parent, dlgProc.GetThunk() );
}
/// <summary>
/// Run dialog as modeless window
/// </summary>
/// <param name="parent">Parent window</param>
/// <param name="accelID">Accelerator ID to use</param>
/// <returns>TRUE on success, FALSE otherwise</returns>
virtual INT_PTR RunModeless( HWND parent = NULL, int accelID = 0 )
{
MSG msg = { 0 };
BOOL bRet = FALSE;
HACCEL hAccel = LoadAcceleratorsW( NULL, MAKEINTRESOURCEW( accelID ) );
_modeless = true;
Win32Thunk<DLGPROC, Dialog> dlgProc( &Dialog::DlgProc, this );
_hwnd = CreateDialogW( NULL, MAKEINTRESOURCE( _dialogID ), parent, dlgProc.GetThunk() );
ShowWindow( _hwnd, SW_SHOW );
while (IsWindow( _hwnd ) && GetMessageW( &msg, NULL, 0, 0 ) > 0)
{
if (TranslateAccelerator( _hwnd, hAccel, &msg ))
continue;
if (!IsDialogMessage( _hwnd, &msg ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
return TRUE;
}
protected:
/// <summary>
/// Close dialog properly
/// </summary>
/// <returns>status</returns>
INT_PTR CloseDialog()
{
if (_modeless)
{
DestroyWindow( _hwnd );
_hwnd = NULL;
}
else
EndDialog( _hwnd, 0 );
return TRUE;
}
/// <summary>
/// Dialog message proc
/// </summary>
INT_PTR DlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
if (_messages.count( message ))
return (this->*_messages[message])(hDlg, message, wParam, lParam);
return FALSE;
}
/// <summary>
/// WM_INITDIALOG handler
/// </summary>
virtual INT_PTR OnInit( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
_hwnd = hDlg;
return TRUE;
}
/// <summary>
/// WM_COMMAND handler
/// </summary>
virtual INT_PTR OnCommand( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
if (_events.count( LOWORD( wParam ) ))
return (this->*_events[LOWORD( wParam )])(hDlg, message, wParam, lParam);
if (_events.count( HIWORD( wParam ) ))
return (this->*_events[HIWORD( wParam )])(hDlg, message, wParam, lParam);
return FALSE;
}
/// <summary>
/// WM_CLOSE handler
/// </summary>
virtual INT_PTR OnClose( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
return CloseDialog();
}
protected:
mapMsgProc _messages; // Message handlers
mapCtrlProc _events; // Event handlers
int _dialogID; // Dialog resource ID
bool _modeless = false; // Modeless dialog
};