int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, char* cmdParam, int cmdShow) {
_set_new_handler(&NewHandler);
// Using exceptions here helps debugging your program
// and protects from unexpected incidents.
try {
// Create top window class
TopWinClass topWinClass(ID_MAIN, hInst, MainWndProc);
// Is there a running instance of this program?
HWND hwndOther = topWinClass.GetRunningWindow ();
if (hwndOther != 0) {
::SetForegroundWindow(hwndOther);
if (::IsIconic(hwndOther)) ::ShowWindow(hwndOther, SW_RESTORE);
return 0;
}
topWinClass.Register();
// Create top window
ResString caption(hInst, ID_CAPTION);
TopWinMaker topWin(topWinClass, caption);
topWin.Create();
topWin.Show(cmdShow);
// The main message loop
MSG msg;
int status;
while ((status = ::GetMessage(&msg, 0, 0, 0)) != 0) {
if (status == –1) return –1;
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
} catch(WinException e) {
char buf [50];
wsprintf(buf, "%s, Error %d", e.GetMessage(), e.GetError());
::MessageBox(0, buf, "Exception", MB_ICONEXCLAMATION | MB_OK);
}
catch (…) {
::MessageBox(0, "Unknown", "Exception", MB_ICONEXCLAMATION | MB_OK);
}
return 0;
}
Давайте, рассмотрим WinClass. Он инкапсулирует предопределенную в Windows структуру WNDCLASSEX и обеспечивает приемлемые значения по умолчанию для всех ее полей. Этот класс получен из более простого класса WinSimpleClass, который Вы могли бы использовать, чтобы инкапсулировать некоторые встроенные в Windows классы (такие как кнопки, списки просмотров, и т.д.).
Я обеспечил примеры методами, которые могут использоваться, чтобы перестроить значения, устанавливаемые по умолчанию. Например, SetBgSysColor изменяет заданный по умолчанию цвет заднего фона окна к одному из предопределенных цветов системы. Метод SetResIcons загружает соответствующие иконки из ресурсов и присоединяетих к оконному классу. Эти иконки затем появятся в верхнем левом углу основного окна и на панели задач Windows.
TopWinClass наследует от WinClass и использует этот метод. Он также подцепляет меню в вершине оконного класса.
class WinSimpleClass {
public:
WinSimpleClass(char const * name, HINSTANCE hInst) : _name (name), _hInstance (hInst) {}
WinSimpleClass (int resId, HINSTANCE hInst);
char const* GetName() const { return _name.c_str (); }
HINSTANCE GetInstance() const { return _hInstance; }
HWND GetRunningWindow();
protected:
HINSTANCE _hInstance;
std::string _name;
};
WinSimpleClass::WinSimpleClass(int resid, hinstance hinst) : _hInstance (hInst) {
ResString resStr (hInst, resId);
_name = resStr;
}
HWND WinSimpleClass::GetRunningWindow () {
HWND hwnd = ::FindWindow(getname(), 0);
if (::IsWindow(hwnd)) {
HWND hwndPopup = ::GetLastActivePopup(hwnd);
if (::IsWindow(hwndpopup)) hwnd = hwndPopup;
} else hwnd = 0;
return hwnd;
}
class WinClass: public WinSimpleClass {
public:
WinClass(char const* className, HINSTANCE hInst, WNDPROC wndProc);
WinClass(int resId, HINSTANCE hInst, WNDPROC wndProc);
void SetBgSysColor (int sysColor) {
_class.hbrBackground = reinterpret_cast<HBRUSH> (sysColor + 1);
}
void SetResIcons(int resId);
void Register();
protected:
void SetDefaults();
WNDCLASSEX _class;
};
WinClass::WinClass(char const * classname, HINSTANCE hInst, WNDPROC wndProc) : WinSimpleClass (className, hInst) {
_class.lpfnWndProc = wndProc;
SetDefaults();
}
WinClass::WinClass(int resid, hinstance hinst, wndproc wndproc) : WinSimpleClass (resId, hInst) {
_class.lpfnWndProc = wndProc;
SetDefaults();
}
void WinClass::SetDefaults () {
// Provide reasonable default values
_class.cbSize = sizeof (WNDCLASSEX);
_class.style = 0;
_class.lpszClassName = GetName();
_class.hInstance = GetInstance();
_class.hIcon = 0;
_class.hIconSm = 0;
_class.lpszMenuName = 0;
_class.cbClsExtra = 0;
_class.cbWndExtra = 0;
_class.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
_class.hCursor = ::LoadCursor(0, IDC_ARROW);
}
void WinClass::SetResIcons (int resid) {
_class.hIcon = reinterpret_cast<HICON>(::LoadImage(_class.hInstance, MAKEINTRESOURCE(resId), IMAGE_ICON, ::GetSystemMetrics(sm_cxicon), ::GetSystemMetrics(sm_cyicon), 0));
// Small icon can be loaded from the same resource
_class.hIconSm = reinterpret_cast<HICON>(::LoadImage(_class.hInstance, MAKEINTRESOURCE(resId), IMAGE_ICON, :: GetSystemMetrics(sm_cxsmicon), ::GetSystemMetrics(sm_cysmicon), 0));
}
void WinClass::Register () {
if (::RegisterClassEx(&_class) == 0) throw WinException("Internal error: RegisterClassEx failed.");
}
class TopWinClass: public WinClass {
public:
TopWinClass(int resId, HINSTANCE hInst, WNDPROC wndProc);
};
TopWinClass::TopWinClass(int resid, HINSTANCE hInst, WNDPROC wndProc) : WinClass (resId, hInst, wndProc) {