Π ΠΈΡ. 1. ΠΠ»Π°ΡΡΡ, Π²ΠΊΠ»ΡΡΠ°Π΅ΠΌΡΠ΅ Π² ΠΎΠ±ΡΠ°Π·Π΅Ρ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ "ΠΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ".
ΠΠ°Π²Π°ΠΉΡΠ΅, Π½Π°ΡΠ½Π΅ΠΌ Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. Π Π½Π°ΡΠ΅ΠΉ ΠΎΠ±ΠΎΠ±ΡΠ΅Π½Π½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ ΠΌΡ Π½ΡΠΆΠ΄Π°Π΅ΠΌΡΡ Π² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠΌ ΠΎΠΊΠ½Π΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΡΠΎΠΊΡ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΠ΅Π΄Π°ΠΊΡΠΎΡ ΡΠ΅ΡΡΡΡΠ°, ΠΌΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΡΠ°Π±Π»ΠΎΠ½ Π΄ΠΈΠ°Π»ΠΎΠ³Π°, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΡΠ΅Π΄ΡΡΠ²Π° ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ Π΄Π²Π΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ, OK ΠΈ CANCEL. ΠΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠ΅ΡΡΡΡΠ° (id) ΡΡΠΎΠ³ΠΎ Π΄ΠΈΠ°Π»ΠΎΠ³Π° β IDD_EDITDIALOG. ΠΠ°ΡΠ΅ΠΌ ΠΌΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ Π½Π°Ρ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ ΡΠΏΠΈΡΠΊΠ° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ EditorData ΠΈ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠΉ ΠΊΠ»Π°ΡΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ° ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ EditorCtrl. ΠΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π²ΡΠ±ΠΈΡΠ°Π΅Ρ ΠΏΡΠ½ΠΊΡ ΠΌΠ΅Π½Ρ Edit, Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΊΠΎΠ΄:
void Controller::Edit(HWND hwnd) {
EditorData data(_model.GetText ());
ControllerFactory<EditorCtrl, EditorData> factory(&data);
ModalDialog dialog(_hInst, hwnd, IDD_EDITDIALOG, &factory);
if (dialog.IsOk()) {
_model.SetText(data.GetName());
// Force repaint
InvalidateRect(hwnd, 0, TRUE);
}
}
Π‘Π½Π°ΡΠ°Π»Π° ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΡΡΡ ΡΡΡΠΎΠΊΠΎΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ EditorData. ΠΠ°ΡΠ΅ΠΌ, ΡΠΎΡΠΌΠΈΡΡΠ΅ΡΡΡ ΡΠ°Π±Π»ΠΎΠ½ ControllerFactory. ΠΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΠ·ΡΠ΅ΠΌ Π΅Π³ΠΎ Π΄Π²ΡΠΌΡ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈΠΌΠΈ ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ EditorCtrl ΠΈ EditorData. ΠΠ±ΡΠ΅ΠΊΡ ΡΠ°Π±ΡΠΈΠΊΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΌ Π½Π° Π½Π°ΡΠΈ Π΄Π°Π½Π½ΡΠ΅. ΠΠ°ΡΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ ModalDialog. ΠΠ½ ΠΏΠΎΠ»ΡΡΠ΅Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° Π½Π°ΡΡ ΡΠ°Π±ΡΠΈΠΊΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°. ΠΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ° ΠΈ Π²ΠΎΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΈΠ· ΡΠΏΠΈΡΠΊΠ° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ². ΠΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΏΡΠΎΠ²Π΅Π΄Π΅Π½ΠΎ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ, ΠΌΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π°Π» Π»ΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ, Π½Π°ΠΆΠΈΠΌΠ°Ρ ΠΊΠ½ΠΎΠΏΠΊΡ OK, ΠΈ Π΅ΡΠ»ΠΈ ΡΠ°ΠΊ, ΡΠΎ ΠΌΡ ΡΠΈΠΊΡΠΈΡΡΠ΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΈΡ Π² Π½Π°ΡΠ΅ΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅. ΠΡΠΎΡ ΡΠΏΠΎΡΠΎΠ± ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° ΡΠ²Π»ΡΠ΅ΡΡΡ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡΠΈΠΏΠΈΡΠ½ΡΠΌ.
ΠΠ»Π°ΡΡ EditorData Π² Π½Π°ΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΏΡΠ΅Π΄Π΅Π»ΡΠ½ΠΎ ΠΏΡΠΎΡΡ.
class EditorData {
public:
enum { maxLen = 128 };
EditorData(char const* name) {
SetName(name);
}
BOOL IsNameOK() { return (_name[0] != '\0'); }
void SetName(char const *name) {
strcpy(_name, name);
}
char const* GetName() { return _name; }
private:
char _name[maxLen];
};
ΠΠ»Π°ΡΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ°, EditorCtrl, ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π²ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ. ΠΡΠ΅ΠΆΠ΄Π΅ Π²ΡΠ΅Π³ΠΎ ΠΎΠ½ Π²ΡΡΡΠ°ΠΈΠ²Π°Π΅Ρ Π² ΡΠ΅Π±Ρ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ. ΠΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½ Π·Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠΌ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ, Π²Π½Π΅Π΄ΡΠ΅Π½Π½ΡΠΌ Π² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ. ΠΠ»Π΅ΠΌΠ΅Π½Ρ ΠΈΠΌΠ΅Π΅Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ IDC_NAME_EDIT, Π·Π°Π΄Π°Π½Π½ΡΠΉΡ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ° ΡΠ΅ΡΡΡΡΠΎΠ². ΠΠΎ-Π²ΡΠΎΡΡΡ , ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅Ρ Ρ ΡΠ°Π½ΠΈΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° EditorData. ΠΡΠΎΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π²Π·ΡΡ ΠΈΠ· Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° DlgController. Π’ΡΠΈ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° DlgController Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΠ°Π½Ρ Π² Π½Π°ΡΠ΅ΠΌ EditorControl. ΠΡΠΎ OnInitDialog, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΏΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π΄ΠΈΠ°Π»ΠΎΠ³ Π±ΡΠ» ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½, OnCommand, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π²ΡΡΠΊΠΈΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° Π»ΡΠ±ΠΎΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° ΠΏΠΎΡΡΠ»Π°Π΅Ρ Π½Π°ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΈ, Π² Π·Π°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, OnNotify, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π½ΠΎΠ²ΡΠΌΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Windows95.
class EditorCtrl : public DlgController {
public:
EditorCtrl(HWND hwndDlg, void *argList) : DlgController(argList), _nameEdit(hwndDlg, IDC_NAME_EDIT) {
_dlgData = (EditorData*)GetArgList();
}
void OnInitDialog(HWND hwnd);
bool OnCommand(HWND hwnd, int ctrlID, int notifyCode);
bool OnNotify(HWND hwnd, int idCtrl, NMHDR *hdr);
private:
Edit _nameEdit;
EditorData *_dlgData;
};
Π ΠΌΠ΅ΡΠΎΠ΄Π΅ OnInitDialog ΠΌΡ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ ΡΡΡΠΎΠΊΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ»Π° ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π° Π² EditorData ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π΅Π΅, ΡΡΠΎΠ±Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
void EditorCtrl::OnInitDialog(HWND hwnd) {
char const* name = _dlgData->GetName();
_nameEdit.SetString(name);
}
OnCommand ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΎΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ². ΠΠ»Π΅ΠΌΠ΅Π½ΡΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Ρ ΠΈΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ°ΠΌΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ β IDC_NAME_EDIT, ΡΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ ΡΡΠΎ ΡΡΠΎ-ΡΠΎ ΠΏΡΠΎΠΈΠ·ΠΎΡΠ»ΠΎ Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠΌ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ. Π Π½Π°ΡΠ΅ΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΌΠ°Π»ΠΎ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΠΈ, ΠΈ ΠΌΡ ΡΠ΅Π°Π³ΠΈΡΡΠ΅ΠΌ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅, ΠΊΠΎΠΏΠΈΡΡΡ ΡΠ΅Π»ΡΡ ΡΡΡΠΎΠΊΡ Π² ΠΎΠ±ΡΠ΅ΠΊΡ EditorData. Π₯ΠΎΡΡ Π²ΡΡΡΠ΅ΡΠ°ΡΡΡΡ ΡΠ»ΡΡΠ°ΠΈ, ΠΊΠΎΠ³Π΄Π° ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΡΡΡ ΡΡΡΠΎΠΊΠΈ ΠΈΠ»ΠΈ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡ Π΅Π΅ Π² Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠΌ Π΄ΡΡΠ³ΠΎΠΌ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ΅ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ΅Π°Π³ΠΈΡΠΎΠ²Π°ΡΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ.
ΠΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½Π°ΠΆΠΈΠΌΠ°Π΅Ρ ΠΊΠ½ΠΎΠΏΠΊΡ OK, ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ IDOK. ΠΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ ΡΡΡΠΎΠΊΡ ΠΈ, Π΅ΡΠ»ΠΈ ΠΎΠ½Π° ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½Π°Ρ, ΡΠΎ Π·Π°ΠΊΠ°Π½ΡΠΈΠ²Π°Π΅ΠΌ Π΄ΠΈΠ°Π»ΠΎΠ³, ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΠΈΠΉ TRUE ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°. ΠΠΎΠ³Π΄Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ β IDCANCEL (ΠΎΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ Cancel) ΠΌΡ Π·Π°ΠΊΠ°Π½ΡΠΈΠ²Π°Π΅ΠΌ Π΄ΠΈΠ°Π»ΠΎΠ³ Ρ ΠΊΠΎΠ΄ΠΎΠΌ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° FALSE.
ΠΠ΅ΡΠΎΠ΄ OnNotify Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π²ΡΠΈΡ ΡΡ Π΄ΠΎ Widnows95, ΡΠ°ΠΊΠΈΡ ΠΊΠ°ΠΊ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ.
bool EditorCtrl::OnCommand(HWND hwnd, int ctrlID, int notifyCode) {
switch (ctrlID) {
case IDC_NAME_EDIT:
if (_nameEdit.IsChanged(notifyCode)) {
char nameBuf [EditorData::maxLen];
int len = _nameEdit.GetLen();
if (len < EditorData::maxLen) {
_nameEdit.GetString(nameBuf, sizeof(nameBuf));
_dlgData->SetName(nameBuf);
}
return true;
}
break;
case IDOK:
if (_dlgData->IsNameOK()) {
EndDialog(hwnd, TRUE);
} else {
MessageBox(hwnd, "Please, enter valid name", "Name Editor", MB_ICONINFORMATION | MB_OK);
}
return true;
case IDCANCEL:
EndDialog(hwnd, FALSE);
return true;
}
return false;
}
bool EditorCtrl::OnNotify(HWND hwnd, int idCtrl, NMHDR *hdr) {
return false;
}
Π’Π΅ΠΏΠ΅ΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΡ Π·Π½Π°Π΅ΡΠ΅ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, Π΄Π°Π²Π°ΠΉΡΠ΅ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ ΠΏΠΎΠ»Π½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΠ±ΡΠ°Π·ΡΠ° "ΠΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ". Π€Π°Π±ΡΠΈΠΊΠ° ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ° β ΠΎΡΠ΅Π½Ρ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠ°Π±Π»ΠΎΠ½ ΠΊΠ»Π°ΡΡΠ°. ΠΡΠ΅, ΡΡΠΎ ΠΎΠ½Π° Π΄Π΅Π»Π°Π΅Ρ, ΡΡΠΎ ΠΏΡΠΈΠ΅ΠΌ ΡΠΏΠΈΡΠΊΠ° ΠΎΠ±ΠΎΠ±ΡΠ΅Π½Π½ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΈ ΡΠΎΡ ΡΠ°Π½Π΅Π½ΠΈΠ΅ Π΅Π³ΠΎ ΡΠ΅ΡΠ΅Π· void-ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ. Π’ΠΎΠ»ΡΠΊΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΉ ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠΌ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅Ρ Π·Π½Π°Π΅Ρ, ΡΠ΅ΠΌ ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠ»Π°ΡΡ, ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½Π½ΡΠΉ Π² ΡΠΏΠΈΡΠΊΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ², ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ½ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ (ΡΠΌ. ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ EditorCtrl).
ΠΠΎΠ΄, ΠΎΠ±ΡΠΈΠΉ Π΄Π»Ρ Π²ΡΠ΅Ρ ΡΠ°Π±ΡΠΈΠΊ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠΎΠ² ΠΈΠ·ΠΎΠ»ΠΈΡΠΎΠ²Π°Π½ Π² ΠΊΠ»Π°ΡΡΠ΅ CtrlFactory ΠΎΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π½Π°ΡΠ»Π΅Π΄ΡΠ΅Ρ ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠ°Π±Π»ΠΎΠ½. Π¨Π°Π±Π»ΠΎΠ½ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΌΠ΅ΡΠΎΠ΄ MakeController, ΡΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π½ΠΎΠ²ΡΠΉ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅Ρ Π΄Π»Ρ ΠΊΠ»Π°ΡΡΠ° ActualCtrl, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠΌ. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ ΠΌΠ΅ΡΠΎΠ΄ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ActualCtrl ΠΊΠ°ΠΊ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° Π΅Π³ΠΎ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ DlgController, ΠΈ ΡΡΠΎ β Π²ΡΠ΅ ΡΠΎ, ΡΡΠΎ Π²ΠΈΠ΄ΠΈΡ ΠΎΡΡΠ°Π»ΡΠ½Π°Ρ ΡΠ°ΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ.
class CtrlFactory {
public:
CtrlFactory(void *argList) : _argList(argList) {}
void *GetArgList() { return _argList; }
virtual DlgController* MakeController(HWND hwndDlg) = 0;
private: void *_argList;
};
template <class ActualCtrl, class ActualArgList>
class ControllerFactory : public CtrlFactory {
public:
ControllerFactory(void *argList) : CtrlFactory(argList) {}
DlgController * MakeController(HWND hwndDlg) {
return new ActualCtrl(hwndDlg, (ActualArgList*)GetArgList());
}
};
ΠΠΈΠΆΠ΅ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π°Π±ΡΡΡΠ°ΠΊΡΠ½ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° DlgController, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΊΠ°ΠΊ ΠΎΡΠ½ΠΎΠ²Π° Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΊΠ»Π°ΡΡΠΎΠ² ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠΎΠ², ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΡ ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠΌ. ΠΡ ΡΠΆΠ΅ Π²ΠΈΠ΄Π΅Π»ΠΈ, ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΡΠΈ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΡ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° EditorCtrl.
class DlgController {
public:
virtual ~DlgController() {} // In case derived class overrides
virtual void OnInitDialog(HWND hwnd) = 0;
virtual bool OnCommand(HWND hwnd, int ctrlID, int notifyCode) = 0;
virtual bool OnNotify(HWND hwnd, int idCtrl, NMHDR *hdr) = 0;
void *GetArgList() { return _argList; }
protected:
DlgController(void *argList) : _argList (argList) {}
private:
void *_argList;
};
Π¦Π΅Π½ΡΡΠ°Π»ΡΠ½ΡΠΌ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠΎΠΌ Π΄Π»Ρ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡΠ°ΡΠ½ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠ»Π°ΡΡ ModalDialog. ΠΠ½ Π΄Π΅Π»Π°Π΅Ρ Π²ΡΡ ΡΠ°Π±ΠΎΡΡ Π² ΡΠ²ΠΎΠ΅ΠΌ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠ΅, Π²ΡΠ·ΡΠ²Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ API DialogBoxParam. ΠΠ°ΡΠ°ΠΌΠ΅ΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠΌΡ ΠΎΠΊΠ½Ρ (ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ, Π΅Π³ΠΎ ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ΅ Π΄ΠΈΠ°Π»ΠΎΠ³Π°) β ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΠ°Π±ΡΠΈΠΊΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ°. ΠΡΠΎΡΠ΅Π΄ΡΡΠ° Π΄ΠΈΠ°Π»ΠΎΠ³Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° ΠΊΠ°ΠΊ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅ΡΠΎΠ΄ (Π½Π΅ Π½ΡΠΆΠ΅Π½ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ: ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ° Π΄ΠΈΠ°Π»ΠΎΠ³Π° Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΠΈΠ· Windows, ΠΏΠΎΡΡΠΎΠΌΡ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ Π΄ΠΎΡΡΡΠΏ ΠΏΠΎ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ).
class ModalDialog {
public:
ModalDialog(HINSTANCE hInst, HWND hwnd, int dlgResource, CtrlFactory *ctrlFactory) {
_result = DialogBoxParam(hInst, MAKEINTRESOURCE(dlgResource), hwnd, (DLGPROC)ModalDialogProc, (LPARAM)ctrlFactory);
}
static BOOL CALLBACK ModalDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
bool IsOk() const { return (_result == β1) ? false : _result != 0; }
private:
int _result;
};
Π Π·Π°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΡΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ° Π΄ΠΈΠ°Π»ΠΎΠ³Π°, ΠΎΠ±ΡΠ°Ρ Π΄Π»Ρ Π²ΡΠ΅Ρ ΡΠΈΠΏΠΎΠ² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ², ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΠΎΡΠ²Π΅ΡΠΈΡΡ Π½Π° ΡΡΠΈ Π²ΠΈΠ΄Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ: WM_INITDIALOG, WM_COMMAND ΠΈ WM_NOTIFY. Π€Π°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ, Π²ΡΠ΅ ΠΎΠ½ΠΈ Π½Π°ΠΏΡΠ°Π²Π»ΡΡΡ ΡΡΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΡ β ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΡ. ΠΠ½ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΏΠΎΠ»ΠΈΠΌΠΎΡΡΠ½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ° Π²ΡΠ·ΡΠ²Π°Ρ Π² Π½Π°ΡΠ°Π»Π΅ ΠΌΠ΅ΡΠΎΠ΄ ΡΠ°Π±ΡΠΈΠΊΠΈ MakeController.
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ, ΠΈΠ· ΡΡΠΎΠΉ ΡΠΎΡΠΊΠΈ ΠΌΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅ΠΌ Windows, ΠΎΡΡΠ»Π΅Π΄ΠΈΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅Ρ. ΠΡ ΡΠΎΡ ΡΠ°Π½ΡΠ΅ΠΌ Π΅Π³ΠΎ ΠΊΠ°ΠΊ GWL_USERDATA β ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠΉ Π΄Π»ΠΈΠ½Π½ΡΠΉ, ΠΊΠΎΡΠΎΡΡΠΉ Π°ΡΡΠΎΡΠΈΠΈΡΡΠ΅ΡΡΡ Ρ ΠΊΠ°ΠΆΠ΄ΡΠΌ ΠΎΠΊΠ½ΠΎΠΌ, Π² ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ Ρ Π½Π°ΡΠΈΠΌ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠΌ, ΠΈ Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΡΠ΅ΡΠ΅Π· Π΅Π³ΠΎ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ ΠΎΠΊΠ½Π°.
template <class T> inline T
GetWinLong(HWND hwnd, int which = GWL_USERDATA) {
return reinterpret_cast<T>(::GetWindowLong(hwnd, which));
}
template <class T> inline void
SetWinLong(HWND hwnd, T value, int which = GWL_USERDATA) {