Базовым классом для большинства элементов управления является SimpleControl. Он получает и сохраняет дескриптор окна специфического элемента управления. Чтобы получить этот дескриптор, необходимо иметь дескриптор родительского окна и идентификатор элемента управления.
class SimpleControl {
public:
SimpleControl(HWND hwndParent, int id) : _hWnd(GetDlgItem(hwndParent, id)) {}
void SetFocus() {
::SetFocus (_hwnd);
}
HWND Hwnd() const { return _hWnd; }
protected:
HWND _hWnd;
};
Ниже представлен пример элемента управления редактированием.
class Edit: public SimpleControl {
public:
Edit(HWND hwndParent, int id) : SimpleControl (hwndParent, id) {}
void SetString(char* buf) {
SendMessage(Hwnd(), WM_SETTEXT, 0, (LPARAM)buf);
}
// code is the HIWORD (wParam)
static BOOL IsChanged (int code) {
return code == EN_CHANGE;
}
int GetLen() {
return SendMessage(Hwnd(), WM_GETTEXTLENGTH, 0, 0);
}
void GetString(char* buf, int len) {
SendMessage(Hwnd(), WM_GETTEXT, (WPARAM)len, (LPARAM)buf);
}
void Select() {
SendMessage(Hwnd(), EM_SETSEL, 0, –1);
}
};
Здесь показано, как элемент управления редактированим может использоваться:
class Controller {
public:
Controller(HWND hwnd);
…
private:
Edit _edit;
char _string[maxLen];
};
Controller::Controller(HWND hwnd) : _edit(hwnd, IDC_EDIT) {
_edit.SetFocus();
…
}
void Controller::Command(HWND hwnd, WPARAM wParam, LPARAM lParam) {
switch (LOWORD(wParam)) {
case IDC_EDIT:
if (_edit.IsChanged(HIWORD (wParam))) {
_edit.GetString(_string, maxLen);
}
break;
…
}
}
Далее: Естественно, что наиболее вероятным местом использования элемента управления является диалоговое окно.
Использование «Контроллера» в диалоге
Англоязычный оригинал находится на сервере компании Reliable Software
Основное окно программы не должно быть универсальным окном, изменяющим свой размер. Много небольших приложений работают лучше в формате диалогового окна. Очевидное преимущество такого подхода заключается в том, что, для размещения элементов управления на поверхности диалога, можно использовать редактор ресурсов. Таким образом реализован пользовательский интерфейс (ПИ) частотного анализатора. Ниже этот полезный подход описан подробнее. Вы можете разгрузить исходный текст простого приложения, которое демонстрирует, описанные методы (любезность Laszlo Radanyi).
Прежде всего мы должны разработать диалоговое окно, используя редактор ресурсов. Мы назначаем идентификаторы всем элементам управления и непосредственно диалогу. В данном примере ресурс диалога имеет идентификатор DLG_MAIN. В процедуре WinMain мы не можем регистрировать окна любого класса, потому что Windows имеет предопределенный класс для диалоговых окон. Вместо того, чтобы создавать окно, мы вызываем функцию CreateDialog, передавая ей указатель на нашу собственную процедуру диалога (объясню позже).
Цикл сообщений данной программы является нестандартным, так как он вызывает функцию IsDialogMessage для каждого сообщения. Эта функция API не только проверяет, направлено ли данное сообщение к диалоговому окну, но и, что более важно, пересылает это сообщение процедуре диалога. Если сообщение не было адресовано диалогу, мы выполняем стандартную трансляцию и диспетчеризацию.
Для удобства, мы храним значение HINSTANCE в глобальной переменной. Этот вариант фактически является предшественником более общего объекта — Приложения. Однако, в данном случае, пример слишком тривиальный, чтобы заслуживать собственного класса.
HINSTANCE TheInstance = 0;
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, char* cmdParam, int cmdShow) {
TheInstance = hInst;
_set_new_handler(&NewHandler);
HWND hDialog = 0;