Читать «Применение Windows API» онлайн - страница 13

А. И. Легалов

И, наконец, чтобы отобразить диалоговое окно, нам нужен дескриптор экземпляра приложения. Стандартный способ восстанавить (отыскать) его состоит в том, чтобы обратиться к внутренней структуре данных Windows, используя соответствующий hwnd.

// Menu command processing

void Controller::Command (int cmd) {

 switch (cmd) {

 case IDM_EXIT:

  ::SendMessage(_hwnd, wm_close, 0, 0l);

  break;

 case IDM_HELP:

  ::MessageBox(_hwnd, "go figure!", "Generic", MB_ICONINFORMATION | MB_OK);

  break;

 case IDM_ABOUT: {

   // Instance handle is available through HWND

   HINSTANCE hInst = WinGetLong<HINSTANCE>(_hwnd, GWL_HINSTANCE);

   ::DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUT), _hwnd, AboutDlgProc);

  }

  break;

 }

}

View, Canvas

Объект "Вид" (Экранный объект) обычно хранит размеры клиентской области. Они обновляются всякий раз, когда контроллер обрабатывает сообщение WM_SIZE. Первое сообщение WM_SIZE посылается во время создания окна и до посылки WM_PAINT, поэтому мы можем безопасно принимать, его. Когда вызывается Paint, размерности клиентской области уже известны.

Графический вывод к окну осуществляется, вызывом соответствующих методов объекта Canvas. В нашем случае, мы печатаем текст, полученный из модели и рисуем вертикальную строку в десяти пикселах от левого края клиентской области.

class View {

public:

 void SetSize(int cxNew, int cyNew) { _cx = cxNew; _cy = cyNew; }

 void Paint(Canvas& canvas, Model& model);

protected:

 int _cx; int _cy;

};

void View::Paint (Canvas& canvas, Model& model) {

 canvas.Text(12, 1, model.GetText(), model.GetLen());

 canvas.Line(10, 0, 10, _cy);

}

Объект "Холст" инкапсулирует то, что, на языке Windows, называется Контекстом устройства. Наш Холст очень прост, он знает только, как печатать текст и рисовать линии, но ваш Холст может иметь много больше методов, которые выполняют творческие функции. Мы больше расскажем о Холсте при описании одной из следующих обучающих программ.

class Canvas {

public:

 operator HDC() { return _hdc; }

 void Line(int x1, int y1, int x2, int y2) {

  ::MoveToEx(_hdc, x1, y1, 0);

  ::LineTo(_hdc, x2, y2);

 }

 void Text(int x, int y, char const* buf, int cBuf) {

  ::TextOut(_hdc, x, y, buf, cbuf);

 }

 void Char(int x, int y, char c) {

  ::TextOut(_hdc, x, y, &c, 1);

 }

protected:

 // Protected constructor: You can't construct

 // a Canvas object, but you may be able

 // to construct objects derived from it.

 Canvas(HDC hdc): _hdc (hdc) {}

 HDC _hdc;

};

Холсты, который Вы создаете, в ответ на сообщение WM_PAINT, имеет специальный вид. Они получают контекст устройства, вызывая BeginPaint и отдают его, вызывая EndPaint. PAINTSTRUCT содержит дополнительную информацию, о некоторой части рабочей области, которая должна быть перерисована, и т.д. Пока мы игнорируем некоторые подробности, но если вы серьезно относитесь к эффективности, Вы должны изучить это более детально.

// Concrete example of canvas.

// Create this object after WM_PAINT message

class PaintCanvas: public Canvas {