/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef BAGEL_MFC_AFXWIN_H #define BAGEL_MFC_AFXWIN_H #include "common/events.h" #include "common/fs.h" #include "graphics/palette.h" #include "graphics/screen.h" #include "bagel/mfc/minwindef.h" #include "bagel/mfc/wingdi.h" #include "bagel/mfc/afx.h" #include "bagel/mfc/afxmsg.h" #include "bagel/mfc/afxstr.h" #include "bagel/mfc/atltypes.h" #include "bagel/mfc/global_functions.h" #include "bagel/mfc/gfx/surface.h" #include "bagel/mfc/gfx/cursor.h" #include "bagel/mfc/gfx/dialog_template.h" #include "bagel/mfc/gfx/fonts.h" #include "bagel/mfc/gfx/text_render.h" #include "bagel/mfc/libs/array.h" #include "bagel/mfc/libs/event_loop.h" #include "bagel/mfc/libs/events.h" #include "bagel/mfc/libs/list.h" #include "bagel/mfc/libs/settings.h" namespace Bagel { namespace MFC { constexpr uint32 DEFAULT_MODAL_RESULT = MKTAG('S', 'C', 'V', 'M'); class CBitmap; class CButton; class CCmdTarget; class CCmdUI; class CDC; class CDocTemplate; class CDocument; class CFrameWnd; class CListBox; class CScrollBar; class CView; class CWinThread; class CWnd; // Dummy class definitions that may need replacing later struct COPYDATASTRUCT {}; struct HELPINFO {}; struct NCCALCSIZE_PARAMS {}; struct NMHDR {}; struct WINDOWPOS {}; /*============================================================================*/ // CMenu class CMenu : public CObject { public: // Constructors CMenu(); bool CreateMenu(); bool CreatePopupMenu(); bool LoadMenu(const char *lpszResourceName); bool LoadMenu(unsigned int nIDResource); bool LoadMenuIndirect(const void *lpMenuTemplate); bool DestroyMenu(); static CMenu *FromHandle(HMENU hMenu); unsigned int CheckMenuItem(unsigned int nIDCheckItem, unsigned int nCheck); }; /*============================================================================*/ // Window message map handling enum AfxSig { AfxSig_end = 0, // [marks end of message map] AfxSig_b_D_v, // bool (CDC*) AfxSig_b_b_v, // bool (bool) AfxSig_b_u_v, // bool (unsigned int) AfxSig_b_h_v, // bool (HANDLE) AfxSig_b_W_uu, // bool (CWnd*, unsigned int, unsigned int) AfxSig_b_W_COPYDATASTRUCT, // bool (CWnd*, COPYDATASTRUCT*) AfxSig_b_v_HELPINFO, // bool (LPHELPINFO); AfxSig_CTLCOLOR, // HBRUSH (CDC*, CWnd*, unsigned int) AfxSig_CTLCOLOR_REFLECT, // HBRUSH (CDC*, unsigned int) AfxSig_i_u_W_u, // int (unsigned int, CWnd*, unsigned int) // ?TOITEM AfxSig_i_uu_v, // int (unsigned int, unsigned int) AfxSig_i_W_uu, // int (CWnd*, unsigned int, unsigned int) AfxSig_i_v_s, // int (uint16 *) AfxSig_l_w_l, // LRESULT (WPARAM, LPARAM) AfxSig_l_uu_M, // LRESULT (unsigned int, unsigned int, CMenu*) AfxSig_v_b_h, // void (bool, HANDLE) AfxSig_v_h_v, // void (HANDLE) AfxSig_v_h_h, // void (HANDLE, HANDLE) AfxSig_v_v_v, // void () AfxSig_v_u_v, // void (unsigned int) AfxSig_v_up_v, // void (uintptr) AfxSig_v_u_u, // void (unsigned int, unsigned int) AfxSig_v_uu_v, // void (unsigned int, unsigned int) AfxSig_v_v_ii, // void (int, int) AfxSig_v_u_uu, // void (unsigned int, unsigned int, unsigned int) AfxSig_v_u_ii, // void (unsigned int, int, int) AfxSig_v_u_W, // void (unsigned int, CWnd*) AfxSig_i_u_v, // int (unsigned int) AfxSig_u_u_v, // unsigned int (unsigned int) AfxSig_b_v_v, // bool () AfxSig_v_w_l, // void (WPARAM, LPARAM) AfxSig_MDIACTIVATE, // void (bool, CWnd*, CWnd*) AfxSig_v_D_v, // void (CDC*) AfxSig_v_M_v, // void (CMenu*) AfxSig_v_M_ub, // void (CMenu*, unsigned int, bool) AfxSig_v_W_v, // void (CWnd*) AfxSig_v_v_W, // void (CWnd*) AfxSig_v_W_uu, // void (CWnd*, unsigned int, unsigned int) AfxSig_v_W_p, // void (CWnd*, CPoint) AfxSig_v_W_h, // void (CWnd*, HANDLE) AfxSig_C_v_v, // HCURSOR () AfxSig_ACTIVATE, // void (unsigned int, CWnd*, bool) AfxSig_SCROLL, // void (unsigned int, unsigned int, CWnd*) AfxSig_SCROLL_REFLECT, // void (unsigned int, unsigned int) AfxSig_v_v_s, // void (uint16 *) AfxSig_v_u_cs, // void (unsigned int, const char *) AfxSig_OWNERDRAW, // void (int, uint16 *) force return true AfxSig_i_i_s, // int (int, uint16 *) AfxSig_u_v_p, // unsigned int (CPoint) AfxSig_u_v_v, // unsigned int () AfxSig_v_b_NCCALCSIZEPARAMS, // void (bool, NCCALCSIZE_PARAMS*) AfxSig_v_v_WINDOWPOS, // void (WINDOWPOS*) AfxSig_v_uu_M, // void (unsigned int, unsigned int, HMENU) AfxSig_v_u_p, // void (unsigned int, CPoint) AfxSig_SIZING, // void (unsigned int, LPRECT) AfxSig_MOUSEWHEEL, // bool (unsigned int, short, CPoint) AfxSig_MOUSEHWHEEL, // void (unsigned int, short, CPoint) AfxSigCmd_v, // void () AfxSigCmd_b, // bool () AfxSigCmd_RANGE, // void (unsigned int) AfxSigCmd_EX, // bool (unsigned int) AfxSigNotify_v, // void (NMHDR*, LRESULT*) AfxSigNotify_b, // bool (NMHDR*, LRESULT*) AfxSigNotify_RANGE, // void (unsigned int, NMHDR*, LRESULT*) AfxSigNotify_EX, // bool (unsigned int, NMHDR*, LRESULT*) AfxSigCmdUI, // void (CCmdUI*) AfxSigCmdUI_RANGE, // void (CCmdUI*, unsigned int) AfxSigCmd_v_pv, // void (void*) AfxSigCmd_b_pv, // bool (void*) AfxSig_l, // LRESULT () AfxSig_l_p, // LRESULT (CPOINT) AfxSig_u_W_u, // unsigned int (CWnd*, unsigned int) AfxSig_v_u_M, // void (unsigned int, CMenu* ) AfxSig_u_u_M, // unsigned int (unsigned int, CMenu* ) AfxSig_u_v_MENUGETOBJECTINFO, // unsigned int (MENUGETOBJECTINFO*) AfxSig_v_M_u, // void (CMenu*, unsigned int) AfxSig_v_u_LPMDINEXTMENU, // void (unsigned int, LPMDINEXTMENU) AfxSig_APPCOMMAND, // void (CWnd*, unsigned int, unsigned int, unsigned int) AfxSig_RAWINPUT, // void (unsigned int, HRAWINPUT) AfxSig_u_u_u, // unsigned int (unsigned int, unsigned int) AfxSig_MOUSE_XBUTTON, // void (unsigned int, unsigned int, CPoint) AfxSig_MOUSE_NCXBUTTON, // void (short, unsigned int, CPoint) AfxSig_INPUTLANGCHANGE, // void (unsigned int, unsigned int) AfxSig_v_u_hkl, // void (unsigned int, HKL) AfxSig_INPUTDEVICECHANGE, // void (unsigned short, HANDLE) AfxSig_l_D_u, // LRESULT (CDC*, unsigned int) AfxSig_i_v_S, // int (const char *) AfxSig_vwpb, // void (HFONT, bool) AfxSig_h_v_v, // HANDLE () AfxSig_h_b_h, // HANDLE (bool, HANDLE) AfxSig_b_v_ii, // bool (int, int) AfxSig_h_h_h, // HANDLE (HANDLE, HANDLE) AfxSig_MDINext, // void (CWnd*, bool) AfxSig_u_u_l, // unsigned int (unsigned int, LPARAM) // Old AfxSig_bD = AfxSig_b_D_v, // bool (CDC*) AfxSig_bb = AfxSig_b_b_v, // bool (bool) AfxSig_bWww = AfxSig_b_W_uu, // bool (CWnd*, unsigned int, unsigned int) AfxSig_hDWw = AfxSig_CTLCOLOR, // HBRUSH (CDC*, CWnd*, unsigned int) AfxSig_hDw = AfxSig_CTLCOLOR_REFLECT, // HBRUSH (CDC*, unsigned int) AfxSig_iwWw = AfxSig_i_u_W_u, // int (unsigned int, CWnd*, unsigned int) AfxSig_iww = AfxSig_i_uu_v, // int (unsigned int, unsigned int) AfxSig_iWww = AfxSig_i_W_uu, // int (CWnd*, unsigned int, unsigned int) AfxSig_is = AfxSig_i_v_s, // int (uint16 *) AfxSig_lwl = AfxSig_l_w_l, // LRESULT (WPARAM, LPARAM) AfxSig_lwwM = AfxSig_l_uu_M, // LRESULT (unsigned int, unsigned int, CMenu*) AfxSig_vv = AfxSig_v_v_v, // void () AfxSig_vw = AfxSig_v_u_v, // void (unsigned int) AfxSig_vww = AfxSig_v_u_u, // void (unsigned int, unsigned int) AfxSig_vww2 = AfxSig_v_uu_v, // void (unsigned int, unsigned int) // both come from wParam AfxSig_vvii = AfxSig_v_v_ii, // void (int, int) // wParam is ignored AfxSig_vwww = AfxSig_v_u_uu, // void (unsigned int, unsigned int, unsigned int) AfxSig_vwii = AfxSig_v_u_ii, // void (unsigned int, int, int) AfxSig_vwl = AfxSig_v_w_l, // void (unsigned int, LPARAM) AfxSig_vbWW = AfxSig_MDIACTIVATE, // void (bool, CWnd*, CWnd*) AfxSig_vD = AfxSig_v_D_v, // void (CDC*) AfxSig_vM = AfxSig_v_M_v, // void (CMenu*) AfxSig_vMwb = AfxSig_v_M_ub, // void (CMenu*, unsigned int, bool) AfxSig_vW = AfxSig_v_W_v, // void (CWnd*) AfxSig_vWww = AfxSig_v_W_uu, // void (CWnd*, unsigned int, unsigned int) AfxSig_vWp = AfxSig_v_W_p, // void (CWnd*, CPoint) AfxSig_vWh = AfxSig_v_W_h, // void (CWnd*, HANDLE) AfxSig_vwW = AfxSig_v_u_W, // void (unsigned int, CWnd*) AfxSig_vwWb = AfxSig_ACTIVATE, // void (unsigned int, CWnd*, bool) AfxSig_vwwW = AfxSig_SCROLL, // void (unsigned int, unsigned int, CWnd*) AfxSig_vwwx = AfxSig_SCROLL_REFLECT, // void (unsigned int, unsigned int) AfxSig_vs = AfxSig_v_v_s, // void (uint16 *) AfxSig_vOWNER = AfxSig_OWNERDRAW, // void (int, uint16 *), force return true AfxSig_iis = AfxSig_i_i_s, // int (int, uint16 *) AfxSig_wp = AfxSig_u_v_p, // unsigned int (CPoint) AfxSig_wv = AfxSig_u_v_v, // unsigned int () AfxSig_vPOS = AfxSig_v_v_WINDOWPOS, // void (WINDOWPOS*) AfxSig_vCALC = AfxSig_v_b_NCCALCSIZEPARAMS, // void (bool, NCCALCSIZE_PARAMS*) AfxSig_vNMHDRpl = AfxSigNotify_v, // void (NMHDR*, LRESULT*) AfxSig_bNMHDRpl = AfxSigNotify_b, // bool (NMHDR*, LRESULT*) AfxSig_vwNMHDRpl = AfxSigNotify_RANGE, // void (unsigned int, NMHDR*, LRESULT*) AfxSig_bwNMHDRpl = AfxSigNotify_EX, // bool (unsigned int, NMHDR*, LRESULT*) AfxSig_bHELPINFO = AfxSig_b_v_HELPINFO, // bool (HELPINFO*) AfxSig_vwSIZING = AfxSig_SIZING, // void (unsigned int, LPRECT) -- return true // signatures specific to CCmdTarget AfxSig_cmdui = AfxSigCmdUI, // void (CCmdUI*) AfxSig_cmduiw = AfxSigCmdUI_RANGE, // void (CCmdUI*, unsigned int) AfxSig_vpv = AfxSigCmd_v_pv, // void (void*) AfxSig_bpv = AfxSigCmd_b_pv, // bool (void*) // Other aliases (based on implementation) AfxSig_vwwh = AfxSig_v_uu_M, // void (unsigned int, unsigned int, HMENU) AfxSig_vwp = AfxSig_v_u_p, // void (unsigned int, CPoint) AfxSig_bw = AfxSig_b_u_v, // bool (unsigned int) AfxSig_bh = AfxSig_b_h_v, // bool (HANDLE) AfxSig_iw = AfxSig_i_u_v, // int (unsigned int) AfxSig_ww = AfxSig_u_u_v, // unsigned int (unsigned int) AfxSig_bv = AfxSig_b_v_v, // bool () AfxSig_hv = AfxSig_C_v_v, // HANDLE () AfxSig_vb = AfxSig_vw, // void (bool) AfxSig_vbh = AfxSig_v_b_h, // void (bool, HANDLE) AfxSig_vbw = AfxSig_vww, // void (bool, unsigned int) AfxSig_vhh = AfxSig_v_h_h, // void (HANDLE, HANDLE) AfxSig_vh = AfxSig_v_h_v, // void (HANDLE) AfxSig_viSS = AfxSig_vwl, // void (int, STYLESTRUCT*) AfxSig_bwl = AfxSig_lwl, AfxSig_vwMOVING = AfxSig_vwSIZING, // void (unsigned int, LPRECT) -- return true AfxSig_vW2 = AfxSig_v_v_W, // void (CWnd*) (CWnd* comes from lParam) AfxSig_bWCDS = AfxSig_b_W_COPYDATASTRUCT, // bool (CWnd*, COPYDATASTRUCT*) AfxSig_bwsp = AfxSig_MOUSEWHEEL, // bool (unsigned int, short, CPoint) AfxSig_vws = AfxSig_v_u_cs, }; #define CN_COMMAND 0 // void () #define CN_UPDATE_COMMAND_UI ((unsigned int)(-1)) // void (CCmdUI*) #define CN_EVENT ((unsigned int)(-2)) // OLE event #define CN_OLECOMMAND ((unsigned int)(-3)) // OLE document command #define CN_OLE_UNREGISTER ((unsigned int)(-4)) // OLE unregister // > 0 are control notifications // < 0 are for MFC's use /* * PeekMessage() Options */ #define PM_NOREMOVE 0x0000 #define PM_REMOVE 0x0001 #define PM_NOYIELD 0x0002 typedef void (CCmdTarget::*AFX_PMSG)(); typedef void (CWnd::*AFX_PMSGW)(); #pragma warning(disable: 4121) struct AFX_MSGMAP_ENTRY { unsigned int nMessage; // windows message unsigned int nCode; // control code or WM_NOTIFY code unsigned int nID; // control ID (or 0 for windows messages) unsigned int nLastID; // used for entries specifying a range of control id's int nSig; // signature type (action) or pointer to message # AFX_PMSG pfn; // routine to call (or special value) }; #pragma warning(default: 4121) struct AFX_MSGMAP { const AFX_MSGMAP *(*pfnGetBaseMap)(); const AFX_MSGMAP_ENTRY *lpEntries; }; #define afx_msg #ifndef AFX_MSG_CALL #define AFX_MSG_CALL #endif typedef void (AFX_MSG_CALL CCmdTarget:: *AFX_PMSG)(); #define DECLARE_MESSAGE_MAP() \ protected: \ static const AFX_MSGMAP *GetThisMessageMap(); \ const AFX_MSGMAP *GetMessageMap() const override; \ /** * GCC complains rightfully about invalid casts with the pointer-to-member-functions used * by MFC to handle the message handling functions. * In practice, casting between these seems safe. * * With C++20, it may be possible to use the MessageMapFunctions enum and * avoid casting by using a designated initializer. */ // (Using *distinct* `#if` calls below is necessary for proper parsing) #if defined(__clang__) && defined(__has_warning) # if __has_warning("-Wcast-function-type") # define COMPILER_HAS_CAST_FUNCTION_TYPE_WARNING 1 # endif #elif GCC_ATLEAST(8, 1) # define COMPILER_HAS_CAST_FUNCTION_TYPE_WARNING 1 #endif #ifdef COMPILER_HAS_CAST_FUNCTION_TYPE_WARNING # define BEGIN_SILENCE_CAST \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"") # define END_SILENCE_CAST \ _Pragma("GCC diagnostic pop") # undef COMPILER_HAS_CAST_FUNCTION_TYPE_WARNING #else # define BEGIN_SILENCE_CAST # define END_SILENCE_CAST #endif #define BEGIN_TEMPLATE_MESSAGE_MAP(theClass, type_name, baseClass) \ template < typename type_name > \ const AFX_MSGMAP *theClass< type_name >::GetMessageMap() const \ { return GetThisMessageMap(); } \ template < typename type_name > \ const AFX_MSGMAP *theClass< type_name >::GetThisMessageMap() { \ typedef theClass< type_name > ThisClass; \ typedef baseClass TheBaseClass; \ BEGIN_SILENCE_CAST \ static const AFX_MSGMAP_ENTRY _messageEntries[] = \ { #define BEGIN_MESSAGE_MAP(theClass, baseClass) \ const AFX_MSGMAP *theClass::GetMessageMap() const \ { return GetThisMessageMap(); } \ const AFX_MSGMAP *theClass::GetThisMessageMap() { \ typedef theClass ThisClass; \ typedef baseClass TheBaseClass; \ { ThisClass *dummy; (void)dummy; } \ BEGIN_SILENCE_CAST \ static const AFX_MSGMAP_ENTRY _messageEntries[] = \ { #define END_MESSAGE_MAP() \ { 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)nullptr } \ }; \ END_SILENCE_CAST \ static const AFX_MSGMAP messageMap = \ { &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \ return &messageMap; \ } \ #define DECLARE_DYNCREATE(class_name) \ DECLARE_DYNAMIC(class_name) \ static CObject *CreateObject(); union MessageMapFunctions { AFX_PMSG pfn; // generic member function pointer // specific type safe variants for WM_COMMAND and WM_NOTIFY messages void (AFX_MSG_CALL CCmdTarget:: *pfn_COMMAND)(); bool(AFX_MSG_CALL CCmdTarget:: *pfn_bCOMMAND)(); void (AFX_MSG_CALL CCmdTarget:: *pfn_COMMAND_RANGE)(unsigned int); bool(AFX_MSG_CALL CCmdTarget:: *pfn_COMMAND_EX)(unsigned int); void (AFX_MSG_CALL CCmdTarget:: *pfn_UPDATE_COMMAND_UI)(CCmdUI *); void (AFX_MSG_CALL CCmdTarget:: *pfn_UPDATE_COMMAND_UI_RANGE)(CCmdUI *, unsigned int); void (AFX_MSG_CALL CCmdTarget:: *pfn_OTHER)(void *); bool(AFX_MSG_CALL CCmdTarget:: *pfn_OTHER_EX)(void *); void (AFX_MSG_CALL CCmdTarget:: *pfn_NOTIFY)(NMHDR *, LRESULT *); bool(AFX_MSG_CALL CCmdTarget:: *pfn_bNOTIFY)(NMHDR *, LRESULT *); void (AFX_MSG_CALL CCmdTarget:: *pfn_NOTIFY_RANGE)(unsigned int, NMHDR *, LRESULT *); bool(AFX_MSG_CALL CCmdTarget:: *pfn_NOTIFY_EX)(unsigned int, NMHDR *, LRESULT *); // Type safe variant for thread messages void (AFX_MSG_CALL CWinThread:: *pfn_THREAD)(WPARAM, LPARAM); // Specific type safe variants for WM-style messages bool(AFX_MSG_CALL CWnd:: *pfn_bD)(CDC *); bool(AFX_MSG_CALL CWnd:: *pfn_bb)(bool); bool(AFX_MSG_CALL CWnd:: *pfn_bWww)(CWnd *, unsigned int, unsigned int); bool(AFX_MSG_CALL CWnd:: *pfn_bHELPINFO)(HELPINFO *); bool(AFX_MSG_CALL CWnd:: *pfn_bWCDS)(CWnd *, COPYDATASTRUCT *); HBRUSH(AFX_MSG_CALL CWnd:: *pfn_hDWw)(CDC *, CWnd *, unsigned int); HBRUSH(AFX_MSG_CALL CWnd:: *pfn_hDw)(CDC *, unsigned int); int (AFX_MSG_CALL CWnd:: *pfn_iwWw)(unsigned int, CWnd *, unsigned int); int (AFX_MSG_CALL CWnd:: *pfn_iww)(unsigned int, unsigned int); int (AFX_MSG_CALL CWnd:: *pfn_iWww)(CWnd *, unsigned int, unsigned int); int (AFX_MSG_CALL CWnd:: *pfn_is)(uint16 *); LRESULT(AFX_MSG_CALL CWnd:: *pfn_lwl)(WPARAM, LPARAM); LRESULT(AFX_MSG_CALL CWnd:: *pfn_lwwM)(unsigned int, unsigned int, CMenu *); void (AFX_MSG_CALL CWnd:: *pfn_vv)(); void (AFX_MSG_CALL CWnd:: *pfn_vw)(unsigned int); void (AFX_MSG_CALL CWnd:: *pfn_vww)(unsigned int, unsigned int); void (AFX_MSG_CALL CWnd:: *pfn_vvii)(int, int); void (AFX_MSG_CALL CWnd:: *pfn_vwww)(unsigned int, unsigned int, unsigned int); void (AFX_MSG_CALL CWnd:: *pfn_vwii)(unsigned int, int, int); void (AFX_MSG_CALL CWnd:: *pfn_vwl)(WPARAM, LPARAM); void (AFX_MSG_CALL CWnd:: *pfn_vbWW)(bool, CWnd *, CWnd *); void (AFX_MSG_CALL CWnd:: *pfn_vD)(CDC *); void (AFX_MSG_CALL CWnd:: *pfn_vM)(CMenu *); void (AFX_MSG_CALL CWnd:: *pfn_vMwb)(CMenu *, unsigned int, bool); void (AFX_MSG_CALL CWnd:: *pfn_vW)(CWnd *); void (AFX_MSG_CALL CWnd:: *pfn_vWww)(CWnd *, unsigned int, unsigned int); void (AFX_MSG_CALL CWnd:: *pfn_vWp)(CWnd *, CPoint); void (AFX_MSG_CALL CWnd:: *pfn_vWh)(CWnd *, HANDLE); void (AFX_MSG_CALL CWnd:: *pfn_vwW)(unsigned int, CWnd *); void (AFX_MSG_CALL CWnd:: *pfn_vwWb)(unsigned int, CWnd *, bool); void (AFX_MSG_CALL CWnd:: *pfn_vwwW)(unsigned int, unsigned int, CWnd *); void (AFX_MSG_CALL CWnd:: *pfn_vwwx)(unsigned int, unsigned int); void (AFX_MSG_CALL CWnd:: *pfn_vs)(uint16 *); void (AFX_MSG_CALL CWnd:: *pfn_vOWNER)(int, uint16 *); // force return true int (AFX_MSG_CALL CWnd:: *pfn_iis)(int, uint16 *); unsigned int(AFX_MSG_CALL CWnd:: *pfn_wp)(CPoint); bool(AFX_MSG_CALL CWnd:: *pfn_bv)(); unsigned int(AFX_MSG_CALL CWnd:: *pfn_wv)(); void (AFX_MSG_CALL CWnd:: *pfn_vPOS)(WINDOWPOS *); void (AFX_MSG_CALL CWnd:: *pfn_vCALC)(bool, NCCALCSIZE_PARAMS *); void (AFX_MSG_CALL CWnd:: *pfn_vwp)(unsigned int, CPoint); void (AFX_MSG_CALL CWnd:: *pfn_vwwh)(unsigned int, unsigned int, HANDLE); bool(AFX_MSG_CALL CWnd:: *pfn_bwsp)(unsigned int, short, CPoint); void (AFX_MSG_CALL CWnd:: *pfn_vws)(unsigned int, const char *); void (AFX_MSG_CALL CWnd:: *pfn_vFb)(HFONT, bool); }; /*============================================================================*/ class CArchive { public: bool IsStoring() const { return false; } }; /*============================================================================*/ // Creation information structure // All fields are optional and may be nullptr struct CCreateContext { // for creating new views const CRuntimeClass *m_pNewViewClass = nullptr; // runtime class of view to create or nullptr CDocument *m_pCurrentDoc = nullptr; // for creating MDI children (CMDIChildWnd::LoadFrame) CDocTemplate *m_pNewDocTemplate = nullptr; // for sharing view/frame state from the original view/frame CView *m_pLastView = nullptr; CFrameWnd *m_pCurrentFrame = nullptr; }; /*============================================================================*/ // Implementation of command routing struct AFX_CMDHANDLERINFO { void (CCmdTarget::*pmf)(); CCmdTarget *pTarget; }; /*============================================================================*/ // WM_NOTIFY support struct AFX_NOTIFY { LRESULT *pResult; NMHDR *pNMHDR; }; /*============================================================================*/ class CGdiObject : public CObject { DECLARE_DYNCREATE(CGdiObject) private: bool _permanent = false; protected: void AfxHookObject(); void AfxUnhookObject(); public: HGDIOBJ m_hObject = nullptr; operator HGDIOBJ() const { return m_hObject; } public: static CGdiObject *FromHandle(HGDIOBJ h); public: ~CGdiObject() override; bool Attach(HGDIOBJ hObject); HGDIOBJ Detach(); bool DeleteObject(); bool operator==(const CGdiObject &obj) const { return obj.m_hObject == m_hObject; } bool operator!=(const CGdiObject &obj) const { return obj.m_hObject != m_hObject; } }; class CPen : public CGdiObject { public: class Impl : public CGdiObjectImpl { public: int _penStyle; int _width; COLORREF _color; public: Impl(int nPenStyle, int nWidth, COLORREF crColor) : _penStyle(nPenStyle), _width(nWidth), _color(crColor) { } }; Impl *pen() const { return (Impl *)m_hObject; } public: CPen() {} CPen(int nPenStyle, int nWidth, COLORREF crColor); ~CPen() override {} bool CreatePen(int nPenStyle, int nWidth, COLORREF crColor); }; class CBrush : public CGdiObject { public: struct Impl : public CGdiObjectImpl { int _type; COLORREF _color = 0; Impl(); Impl(COLORREF crColor); Impl(int nIndex, COLORREF crColor); Impl(CBitmap *pBitmap); ~Impl() override {} byte getColor() const; }; Impl *brush() const { return (Impl *)m_hObject; } public: static CBrush *FromHandle(HGDIOBJ h) { return (CBrush *)CGdiObject::FromHandle(h); } public: CBrush(); CBrush(CBitmap *pBitmap); CBrush(COLORREF crColor); CBrush(int nIndex, COLORREF crColor); ~CBrush() override { } bool CreateSolidBrush(COLORREF crColor); bool CreateBrushIndirect(const LOGBRUSH *lpLogBrush); bool CreateStockObject(int nIndex); }; class CFont : public CGdiObject { public: struct Impl : public CGdiObjectImpl { public: Gfx::Font *_font; public: Impl(Gfx::Font *font) : _font(font) {} ~Impl() override {} operator Gfx::Font *() const { return _font; } }; Impl *font() const { return (Impl *)m_hObject; } public: static CFont *FromHandle(HGDIOBJ h) { return (CFont *)CGdiObject::FromHandle(h); } public: ~CFont() override {} bool CreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int nWeight, byte bItalic, byte bUnderline, byte cStrikeOut, byte nCharSet, byte nOutPrecision, byte nClipPrecision, byte nQuality, byte nPitchAndFamily, const char *lpszFacename); bool CreateFontIndirect(const LOGFONT *lpLogFont); }; class CBitmap : public CGdiObject { public: struct Impl : public CGdiObjectImpl, public Gfx::Surface { ~Impl() override {} }; Impl *bitmap() const { return (Impl *)m_hObject; } public: static CBitmap *FromHandle(HGDIOBJ h) { return (CBitmap *)CGdiObject::FromHandle(h); } public: ~CBitmap() override { } bool Attach(HBITMAP hObject); HBITMAP Detach(); bool CreateCompatibleBitmap(CDC *pDC, int nWidth, int nHeight); bool CreateBitmap(int nWidth, int nHeight, unsigned int nPlanes, unsigned int nBitcount, const void *lpBits); int GetObject(int nCount, void *lpObject) const; long GetBitmapBits(long dwCount, void *lpBits) const; bool GetBitmap(BITMAP *pBitMap) const { return GetObject(sizeof(BITMAP), pBitMap); } }; class CPalette : public CGdiObject { public: struct Impl : public CGdiObjectImpl, public Graphics::Palette { Impl(const LPLOGPALETTE pal); Impl(const Graphics::Palette &pal); ~Impl() override {} }; Impl *palette() const { return (Impl *)m_hObject; } public: static CPalette *FromHandle(HGDIOBJ h) { return (CPalette *)CGdiObject::FromHandle(h); } public: ~CPalette() override { } bool CreatePalette(LPLOGPALETTE lpLogPalette); int GetObject(int nCount, void *lpObject) const; unsigned int GetEntryCount() const; unsigned int GetPaletteEntries(unsigned int nStartIndex, unsigned int nNumEntries, LPPALETTEENTRY lpPaletteColors) const; unsigned int SetPaletteEntries(unsigned int nStartIndex, unsigned int nNumEntries, LPPALETTEENTRY lpPaletteColors); unsigned int SetPaletteEntries(const Graphics::Palette &pal); bool AnimatePalette(unsigned int nStartIndex, unsigned int nNumEntries, const PALETTEENTRY *lpPaletteColors); unsigned int GetNearestPaletteIndex(COLORREF crColor); bool isEmpty() const { return !palette() || palette()->empty(); } }; class CRgn : public CGdiObject { public: Common::Array _points; Common::Rect _rect; int _polyFillMode = 0; public: ~CRgn() override { } bool CreateRectRgn(int x1, int y1, int x2, int y2); bool CreateRectRgnIndirect(LPCRECT lpRect); bool CreatePolygonRgn(const POINT *lpPoints, int nCount, int nPolyFillMode); }; class CDC : public CObject { DECLARE_DYNCREATE(CDC) friend class CWnd; private: bool _permanent = false; int _stretchMode = STRETCH_ANDSCANS; protected: void AfxHookObject(); void AfxUnhookObject(); public: class DefaultBitmap : public CBitmap { public: ~DefaultBitmap() override { }; }; class Impl : public Gfx::TextRender { private: CWnd *m_pWnd = nullptr; DefaultBitmap _defaultBitmap; Common::Point _linePos; COLORREF _bkColor = RGB(255, 255, 255); int _bkMode = TRANSPARENT; COLORREF _textColor = 0; uint _textAlign = TA_LEFT; int _drawMode = 0; bool _paletteRealized = false; uint getPenColor() const; uint getBrushColor() const; uint32 *getPaletteMap(const CDC::Impl *srcImpl); public: HBITMAP _bitmap; HPEN _pen; HFONT _font; HBRUSH _brush; HPALETTE _palette = nullptr; CPalette *_cPalette = nullptr; bool m_bForceBackground = false; bool _hasLogicalPalette = false; public: Impl(CWnd *wndOwner = nullptr); Impl(HDC srcDc); HGDIOBJ Attach(HGDIOBJ gdiObj); Gfx::Surface *getSurface() const; const Graphics::PixelFormat &getFormat() const; void setFormat(const Graphics::PixelFormat &format); void setScreenRect(); void setScreenRect(const Common::Rect &r); HPALETTE selectPalette(HPALETTE pal, bool bForceBackground); CPalette *selectPalette(CPalette *pal, bool bForceBackground); unsigned int realizePalette(); COLORREF GetNearestColor(COLORREF crColor) const; void fillSolidRect(LPCRECT lpRect, COLORREF clr); void fillSolidRect(int x, int y, int cx, int cy, COLORREF clr); void fillRect(const Common::Rect &r, COLORREF crColor); void drawRect(const Common::Rect &r, CBrush *brush); void frameRect(const Common::Rect &r, CBrush *brush); void frameRgn(const CRgn *pRgn, CBrush *brush, int nWidth, int nHeight); void floodFill(int x, int y, COLORREF crColor); void floodFill(int x, int y, COLORREF crColor, unsigned int nFillType); void rectangle(LPCRECT lpRect); void rectangle(int x1, int y1, int x2, int y2); void draw3dRect(const CRect &rect, COLORREF clrTopLeft, COLORREF clrBottomRight); void drawFocusRect(const CRect &rect); void ellipse(const Common::Rect &r, COLORREF crColor); void ellipse(LPCRECT lpRect); void ellipse(int x1, int y1, int x2, int y2); void bitBlt(int x, int y, int nWidth, int nHeight, CDC *pSrcDC, int xSrc, int ySrc, uint32 dwRop); void stretchBlt(int x, int y, int nWidth, int nHeight, CDC *pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, uint32 dwRop); void moveTo(int x, int y); void lineTo(int x, int y); COLORREF getPixel(int x, int y) const; int setROP2(int nDrawMode); // Text functions COLORREF setBkColor(COLORREF crColor); COLORREF getBkColor() const; COLORREF getBkPixel() const; int setBkMode(int nBkMode); COLORREF setTextColor(COLORREF crColor); bool textOut(int x, int y, const char *lpszString, int nCount, int nTabPositions = 0, const int *lpnTabStopPositions = nullptr, int nTabOrigin = 0, CSize *size = nullptr); bool textOut(int x, int y, const CString &str, int nTabPositions = 0, const int *lpnTabStopPositions = nullptr, int nTabOrigin = 0, CSize *size = nullptr); bool extTextOut(int x, int y, unsigned int nOptions, LPCRECT lpRect, const char *lpszString, unsigned int nCount, int *lpDxWidths); bool extTextOut(int x, int y, unsigned int nOptions, LPCRECT lpRect, const CString &str, int *lpDxWidths); CSize tabbedTextOut(int x, int y, const char *lpszString, int nCount, int nTabPositions, const int *lpnTabStopPositions, int nTabOrigin); CSize tabbedTextOut(int x, int y, const CString &str, int nTabPositions, const int *lpnTabStopPositions, int nTabOrigin); int drawText(const char *lpszString, int nCount, LPRECT lpRect, unsigned int nFormat, int nTabPositions = 0, const int *lpnTabStopPositions = nullptr, int nTabOrigin = 0, CSize *size = nullptr); int drawText(const CString &str, LPRECT lpRect, unsigned int nFormat, int nTabPositions = 0, const int *lpnTabStopPositions = nullptr, int nTabOrigin = 0, CSize *size = nullptr); CSize getTextExtent(const char *lpszString, int nCount) const; CSize getTextExtent(const CString &str) const; CSize getOutputTextExtent(const char *lpszString, int nCount) const; CSize getOutputTextExtent(const CString &str) const; CSize getTabbedTextExtent(const char *lpszString, int nCount, int nTabPositions, int *lpnTabStopPositions) const; CSize getTabbedTextExtent(const CString &str, int nTabPositions, int *lpnTabStopPositions) const; CSize getOutputTabbedTextExtent(const char *lpszString, int nCount, int nTabPositions, int *lpnTabStopPositions) const; CSize getOutputTabbedTextExtent(const CString &str, int nTabPositions, int *lpnTabStopPositions) const; bool grayString(CBrush *pBrush, bool(CALLBACK *lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight); unsigned int getTextAlign() const; unsigned int setTextAlign(unsigned int nFlags); bool getTextMetrics(LPTEXTMETRIC lpMetrics) const; }; public: HDC m_hDC = nullptr; static CDC *FromHandle(HDC hDC); public: ~CDC() override; operator HDC() const { return m_hDC; } Impl *impl() const { return static_cast(m_hDC); } bool CreateDC(const char *lpszDriverName, const char *lpszDeviceName, const char *lpszOutput, const void *lpInitData); bool CreateCompatibleDC(CDC *pDC); bool DeleteDC(); bool Attach(HDC hDC); HDC Detach(); int SetStretchBltMode(int nStretchMode); int GetDeviceCaps(int nIndex) const; // Mapping Functions int GetMapMode() const; CPoint GetViewportOrg() const; virtual int SetMapMode(int nMapMode); // Viewport Origin virtual CPoint SetViewportOrg(int x, int y); CPoint SetViewportOrg(POINT point); virtual CPoint OffsetViewportOrg(int nWidth, int nHeight); // Clipping Functions virtual int GetClipBox(LPRECT lpRect) const; void setClipRect(const Common::Rect &r); void resetClipRect(); virtual bool PtVisible(int x, int y); bool PtVisible(POINT point); virtual bool RectVisible(LPCRECT lpRect); int SelectClipRgn(CRgn *pRgn); int ExcludeClipRect(int x1, int y1, int x2, int y2); int ExcludeClipRect(LPCRECT lpRect); int ExcludeUpdateRgn(CWnd *pWnd); int IntersectClipRect(int x1, int y1, int x2, int y2); int IntersectClipRect(LPCRECT lpRect); int OffsetClipRgn(int x, int y); int OffsetClipRgn(SIZE size); int SelectClipRgn(CRgn *pRgn, int nMode); int SetROP2(int nDrawMode); bool DPtoLP(LPPOINT lpPoints, int nCount = 1); bool DPtoLP(RECT *lpRect); bool LPtoDP(LPPOINT lpPoints, int nCount = 1); bool LPtoDP(RECT *lpRect); bool BitBlt(int x, int y, int nWidth, int nHeight, CDC *pSrcDC, int xSrc, int ySrc, uint32 dwRop); bool StretchBlt(int x, int y, int nWidth, int nHeight, CDC *pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, uint32 dwRop); void Ellipse(LPCRECT lpRect); void Ellipse(int x1, int y1, int x2, int y2); void FrameRect(LPCRECT lpRect, CBrush *pBrush); void Draw3dRect(const CRect &rect, COLORREF clrTopLeft, COLORREF clrBottomRight); void DrawFocusRect(const CRect &rect); void FillRect(LPCRECT lpRect, CBrush *pBrush); void FillSolidRect(LPCRECT lpRect, COLORREF crColor); bool FloodFill(int x, int y, COLORREF crColor); bool FloodFill(int x, int y, COLORREF crColor, unsigned int nFillType); void Rectangle(LPCRECT lpRect); void Rectangle(int x1, int y1, int x2, int y2); bool DrawEdge(LPRECT lpRect, unsigned int nEdge, unsigned int nFlags); bool Pie( int x1, int y1, // Upper-left corner of bounding rectangle int x2, int y2, // Lower-right corner of bounding rectangle int x3, int y3, // Starting point of the arc (on the ellipse) int x4, int y4 // Ending point of the arc (on the ellipse) ); bool Pie( LPCRECT lpRect, // Pointer to bounding rectangle const POINT &ptStart, // Start point of arc const POINT &ptEnd // End point of arc ); bool FrameRgn(CRgn *pRgn, CBrush *pBrush, int nWidth, int nHeight); void MoveTo(int x, int y); void LineTo(int x, int y); COLORREF GetPixel(int x, int y) const; COLORREF GetPixel(const POINT &point) const; virtual CGdiObject *SelectStockObject(int nIndex); CPen *SelectObject(CPen *pPen); CBrush *SelectObject(CBrush *pBrush); virtual CFont *SelectObject(CFont *pFont); CBitmap *SelectObject(CBitmap *pBitmap); int SelectObject(CRgn *pRgn); // special return for regions CGdiObject *SelectObject(CGdiObject *pObject); HGDIOBJ SelectObject(HGDIOBJ hGdiObj); COLORREF GetNearestColor(COLORREF crColor) const; CPalette *SelectPalette(CPalette *pPalette, bool bForceBackground); unsigned int RealizePalette(); void UpdateColors(); virtual COLORREF SetBkColor(COLORREF crColor); COLORREF GetBkColor() const; int SetBkMode(int nBkMode); // Text Functions virtual COLORREF SetTextColor(COLORREF crColor); virtual bool TextOut(int x, int y, const char *lpszString, int nCount); bool TextOut(int x, int y, const CString &str); virtual bool ExtTextOut(int x, int y, unsigned int nOptions, LPCRECT lpRect, const char *lpszString, unsigned int nCount, int *lpDxWidths); bool ExtTextOut(int x, int y, unsigned int nOptions, LPCRECT lpRect, const CString &str, int *lpDxWidths); virtual CSize TabbedTextOut(int x, int y, const char *lpszString, int nCount, int nTabPositions, int *lpnTabStopPositions, int nTabOrigin); CSize TabbedTextOut(int x, int y, const CString &str, int nTabPositions, int *lpnTabStopPositions, int nTabOrigin); int DrawText(const char *lpszString, int nCount, LPRECT lpRect, unsigned int nFormat); int DrawText(const CString &str, LPRECT lpRect, unsigned int nFormat); CSize GetTextExtent(const char *lpszString, int nCount) const; CSize GetTextExtent(const CString &str) const; CSize GetOutputTextExtent(const char *lpszString, int nCount) const; CSize GetOutputTextExtent(const CString &str) const; CSize GetTabbedTextExtent(const char *lpszString, int nCount, int nTabPositions, int *lpnTabStopPositions) const; CSize GetTabbedTextExtent(const CString &str, int nTabPositions, int *lpnTabStopPositions) const; CSize GetOutputTabbedTextExtent(const char *lpszString, int nCount, int nTabPositions, int *lpnTabStopPositions) const; CSize GetOutputTabbedTextExtent(const CString &str, int nTabPositions, int *lpnTabStopPositions) const; virtual bool GrayString(CBrush *pBrush, bool(CALLBACK *lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight); unsigned int GetTextAlign() const; unsigned int SetTextAlign(unsigned int nFlags); bool GetTextMetrics(LPTEXTMETRIC lpMetrics) const; }; /*============================================================================*/ // CDC Helpers class CPaintDC : public CDC { DECLARE_DYNAMIC(CPaintDC) protected: PAINTSTRUCT m_ps; HWND m_hWnd = nullptr; public: explicit CPaintDC(CWnd *pWnd); ~CPaintDC() override; }; class CCmdTarget : public CObject { DECLARE_DYNAMIC(CCmdTarget) protected: const AFX_MSGMAP_ENTRY *LookupMessage(unsigned int message); const AFX_MSGMAP_ENTRY *AfxFindMessageEntry( const AFX_MSGMAP_ENTRY *lpEntry, unsigned int nMsg, unsigned int nCode, unsigned int nID); bool _AfxDispatchCmdMsg(CCmdTarget *pTarget, unsigned int nID, int nCode, AFX_PMSG pfn, void *pExtra, unsigned int nSig, AFX_CMDHANDLERINFO *pHandlerInfo); public: ~CCmdTarget() override { } static const AFX_MSGMAP *GetThisMessageMap(); virtual const AFX_MSGMAP *GetMessageMap() const { return GetThisMessageMap(); } /** * Adds or remove a wait mouse cursor * @param nCode 0 => restore, 1=> begin, -1=> end */ virtual void DoWaitCursor(int nCode); void BeginWaitCursor(); void EndWaitCursor(); void RestoreWaitCursor(); bool OnCmdMsg(unsigned int nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo); }; class CCmdUI { public: bool m_bContinueRouting = false; int m_nID = 0; }; typedef Libs::Array ViewArray; class CDocument : public CCmdTarget { DECLARE_DYNAMIC(CDocument) private: CString _title; CString _unusedPathName; bool m_bModified = false; ViewArray m_viewList; public: bool m_bAutoDelete = true; // default to auto delete document bool m_bEmbedded = false; // default to file-based document CDocTemplate *m_pDocTemplate = nullptr; public: ~CDocument() override {} void UpdateAllViews(CView *pSender, LPARAM lHint = 0, CObject *pHint = nullptr); POSITION GetFirstViewPosition(); CView *GetNextView(POSITION &rPosition) const; const CString &GetTitle() const; virtual void SetTitle(const char *lpszTitle); const CString &GetPathName() const; virtual void SetPathName(const char *lpszPathName, bool bAddToMRU = true); virtual void ClearPathName(); virtual bool IsModified(); virtual void SetModifiedFlag(bool bModified = true); virtual void ReportSaveLoadException(const char *lpszPathName, CException *e, bool bSaving, unsigned int nIDPDefault); bool SaveModified(); void AddView(CView *pView); void RemoveView(CView *pView); // Delete doc items etc virtual void DeleteContents(); virtual bool OnNewDocument() { return true; } virtual bool OnOpenDocument(const char *lpszPathName) { return true; } virtual void OnFileSaveAs() {} virtual void OnCloseDocument(); virtual void OnChangedViewList(); virtual void PreCloseFrame(CFrameWnd *pFrame) {} virtual void UpdateFrameCounts() {} DECLARE_MESSAGE_MAP() }; typedef struct tagCREATESTRUCTA { void * lpCreateParams = nullptr; HINSTANCE hInstance = 0; HMENU hMenu = 0; HWND hwndParent = 0; int cy = 0; int cx = 0; int y = 0; int x = 0; long style = 0; const char * lpszName = nullptr; const char * lpszClass = nullptr; uint32 dwExStyle = 0; } CREATESTRUCT, *LPCREATESTRUCT; // CWnd::m_nFlags (generic to CWnd) #define WF_TOOLTIPS 0x0001 // window is enabled for tooltips #define WF_TEMPHIDE 0x0002 // window is temporarily hidden #define WF_STAYDISABLED 0x0004 // window should stay disabled #define WF_MODALLOOP 0x0008 // currently in modal loop #define WF_CONTINUEMODAL 0x0010 // modal loop should continue running #define WF_OLECTLCONTAINER 0x0100 // some descendant is an OLE control #define WF_TRACKINGTOOLTIPS 0x0400 // window is enabled for tracking tooltips class CWnd : public CCmdTarget { DECLARE_DYNCREATE(CWnd) protected: static const MSG *GetCurrentMessage(); virtual void DoDataExchange(CDataExchange *dataExch) {} virtual bool PreCreateWindow(CREATESTRUCT &cs) { return true; } void createDialogIndirect(LPCDLGTEMPLATE dlgTemplate); DECLARE_MESSAGE_MAP() protected: Libs::Array _ownedControls; CDC *_pDC = nullptr; HFONT _hFont; HBRUSH _hBrush; HPEN _hPen; HPALETTE _hPalette; protected: virtual bool OnCommand(WPARAM wParam, LPARAM lParam); virtual bool OnNotify(WPARAM wParam, LPARAM lParam, LRESULT *pResult) { return false; } virtual void OnActivate(unsigned int nState, CWnd *pWndOther, bool bMinimized); virtual LRESULT DefWindowProc(unsigned int nMsg, WPARAM wParam, LPARAM lParam) { return 0; } virtual void OnSetFont(CFont *pFont) { } bool OnWndMsg(unsigned int message, WPARAM wParam, LPARAM lParam, LRESULT *pResult); afx_msg void OnActivateApp(bool bActive, uint32 dwThreadID) {} afx_msg LRESULT OnActivateTopLevel(WPARAM, LPARAM) { return 0; } afx_msg void OnCancelMode() {} afx_msg void OnChildActivate() {} afx_msg void OnClose(); afx_msg void OnContextMenu(CWnd *pWnd, CPoint pos) {} afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct) { return 0; } afx_msg HBRUSH OnCtlColor(CDC *pDC, CWnd *pWnd, unsigned int nCtlColor) { return 0; } afx_msg void OnDestroy() {} afx_msg void OnEnable(bool bEnable) {} afx_msg void OnEndSession(bool bEnding) {} afx_msg void OnEnterIdle(unsigned int nWhy, CWnd *pWho) {} afx_msg bool OnEraseBkgnd(CDC *pDC) { return false; } afx_msg void OnIconEraseBkgnd(CDC *pDC) {} afx_msg void OnKillFocus(CWnd *pNewWnd) {} afx_msg void OnMenuSelect(unsigned int nItemID, unsigned int nFlags, HMENU hSysMenu) {} afx_msg void OnMove(int x, int y) {} afx_msg void OnPaint() {} afx_msg void OnSyncPaint() {} afx_msg void OnParentNotify(unsigned int message, LPARAM lParam) {} afx_msg unsigned int OnNotifyFormat(CWnd *pWnd, unsigned int nCommand) { return 0; } afx_msg HCURSOR OnQueryDragIcon() { return 0; } afx_msg bool OnQueryEndSession() { return false; } afx_msg bool OnQueryOpen() { return false; } afx_msg void OnSetFocus(CWnd *pOldWnd) {} afx_msg void OnShowWindow(bool bShow, unsigned int nStatus); afx_msg void OnSize(unsigned int nType, int cx, int cy) {} afx_msg void OnTCard(unsigned int idAction, uint32 dwActionData) {} afx_msg void OnSessionChange(unsigned int nSessionState, unsigned int nId) {} afx_msg void OnChangeUIState(unsigned int nAction, unsigned int nUIElement) {} afx_msg void OnUpdateUIState(unsigned int nAction, unsigned int nUIElement) {} afx_msg unsigned int OnQueryUIState() { return 0; } afx_msg bool OnQueryNewPalette(); // Nonclient-Area message handler member functions afx_msg bool OnNcActivate(bool bActive) { return false; } afx_msg bool OnNcCreate(LPCREATESTRUCT lpCreateStruct) { return false; } afx_msg void OnNcDestroy(); virtual afx_msg void PostNcDestroy() {} afx_msg LRESULT OnNcHitTest(CPoint point) { return 0; } afx_msg void OnNcLButtonDblClk(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcLButtonDown(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcLButtonUp(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcMButtonDblClk(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcMButtonDown(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcMButtonUp(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcMouseHover(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcMouseLeave() {} afx_msg void OnNcMouseMove(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcPaint() {} afx_msg void OnNcRButtonDblClk(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcRButtonDown(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcRButtonUp(unsigned int nHitTest, CPoint point) {} afx_msg void OnNcXButtonDown(short zHitTest, unsigned int nButton, CPoint point) {} afx_msg void OnNcXButtonUp(short zHitTest, unsigned int nButton, CPoint point) {} afx_msg void OnNcXButtonDblClk(short zHitTest, unsigned int nButton, CPoint point) {} // System message handler member functions afx_msg void OnDropFiles(HDROP hDropInfo) {} afx_msg void OnPaletteIsChanging(CWnd *pRealizeWnd) {} afx_msg void OnSysChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg void OnSysCommand(unsigned int nID, LPARAM lParam) {} afx_msg void OnSysDeadChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg void OnSysKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg void OnSysKeyUp(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg bool OnAppCommand(CWnd *pWnd, unsigned int nCmd, unsigned int nDevice, unsigned int nKey) { return false; } afx_msg void OnRawInput(unsigned int nInputCode, HRAWINPUT hRawInput) {} afx_msg void OnCompacting(unsigned int nCpuTime) {} afx_msg void OnDevModeChange(_In_z_ uint16 * lpDeviceName) {} afx_msg void OnFontChange() {} afx_msg void OnPaletteChanged(CWnd *pFocusWnd) {} afx_msg void OnSpoolerStatus(unsigned int nStatus, unsigned int nJobs) {} afx_msg void OnSysColorChange() {} afx_msg void OnTimeChange() {} afx_msg void OnSettingChange(unsigned int uFlags, const char *lpszSection) {} afx_msg void OnWinIniChange(const char *lpszSection) {} afx_msg unsigned int OnPowerBroadcast(unsigned int nPowerEvent, LPARAM lEventData) { return 0; } afx_msg void OnUserChanged() {} afx_msg void OnInputLangChange(unsigned int nCharSet, unsigned int nLocaleId) {} afx_msg void OnInputLangChangeRequest(unsigned int nFlags, unsigned int nLocaleId) {} afx_msg void OnInputDeviceChange(unsigned short nFlags, HANDLE hDevice) {} // Input message handler member functions afx_msg void OnChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg void OnDeadChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg void OnUniChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg void OnHScroll(unsigned int nSBCode, unsigned int nPos, CScrollBar *pScrollBar) {} afx_msg void OnVScroll(unsigned int nSBCode, unsigned int nPos, CScrollBar *pScrollBar) {} afx_msg void OnKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg void OnKeyUp(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) {} afx_msg void OnHotKey(unsigned int nHotKeyId, unsigned int nKey1, unsigned int nKey2) {} afx_msg void OnLButtonDblClk(unsigned int nFlags, CPoint point) {} afx_msg void OnLButtonDown(unsigned int nFlags, CPoint point) {} afx_msg void OnLButtonUp(unsigned int nFlags, CPoint point) {} afx_msg void OnMButtonDblClk(unsigned int nFlags, CPoint point) {} afx_msg void OnMButtonDown(unsigned int nFlags, CPoint point) {} afx_msg void OnMButtonUp(unsigned int nFlags, CPoint point) {} afx_msg void OnXButtonDblClk(unsigned int nFlags, unsigned int nButton, CPoint point) {} afx_msg void OnXButtonDown(unsigned int nFlags, unsigned int nButton, CPoint point) {} afx_msg void OnXButtonUp(unsigned int nFlags, unsigned int nButton, CPoint point) {} afx_msg int OnMouseActivate(CWnd *pDesktopWnd, unsigned int nHitTest, unsigned int message) { return 0; } afx_msg void OnMouseHover(unsigned int nFlags, CPoint point) {} afx_msg void OnMouseLeave() {} afx_msg void OnMouseMove(unsigned int nFlags, CPoint point) {} afx_msg void OnMouseHWheel(unsigned int nFlags, short zDelta, CPoint pt) {} afx_msg bool OnMouseWheel(unsigned int nFlags, short zDelta, CPoint pt) { return false; } afx_msg void OnRButtonDblClk(unsigned int nFlags, CPoint point) {} afx_msg void OnRButtonDown(unsigned int nFlags, CPoint point) {} afx_msg void OnRButtonUp(unsigned int nFlags, CPoint point) {} afx_msg bool OnSetCursor(CWnd *pWnd, unsigned int nHitTest, unsigned int message); afx_msg void OnTimer(uintptr nIDEvent) {} // Control message handler member functions afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct); afx_msg unsigned int OnGetDlgCode() { return 0; } afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) {} afx_msg int OnCharToItem(unsigned int nChar, CListBox *pListBox, unsigned int nIndex) { return 0; } afx_msg int OnVKeyToItem(unsigned int nKey, CListBox *pListBox, unsigned int nIndex) { return 0; } afx_msg void OnSetFont(HFONT hFont, bool bRedraw); virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {} HWND Detach(); protected: Common::HashMap _children; int m_nFlags = 0; int _itemState = 0; int _controlId = 0; protected: /** * Returns true if the given message should * be sent recursively to all child controls * in addition to the current. */ static bool isRecursiveMessage(unsigned int message); public: // For ScummVM the m_hWnd just points to the window itself, // so it'll be set up once in the constructor CWnd *m_hWnd = nullptr; CWnd *m_pParentWnd = nullptr; int m_nClassStyle = 0; int m_nStyle = 0; int _modalResult = DEFAULT_MODAL_RESULT; bool _hasFocus = false; CString _windowText; Common::Rect _windowRect; Common::Rect _updateRect; Common::Rect _updatingRect; bool _updateErase = false; public: /** * Gets the handle for the wnd from the handle map */ static CWnd *FromHandlePermanent(HWND hWnd); /** * Gets the handle for the wnd. For ScummVM, * all window hWnd point to themselves. We just * use the handle map as a convenient way to * prevent messages being sent to destroyed windows. * As such, internally FromHandle uses the * FromHandlePermnanent function only */ static CWnd *FromHandle(HWND hWnd); public: CWnd(); ~CWnd() override; bool Create(const char *lpszClassName, const char *lpszWindowName, uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID, CCreateContext *pContext = nullptr); bool CreateEx(uint32 dwExStyle, const char *lpszClassName, const char *lpszWindowName, uint32 dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, LPARAM nIDorHMenu, void *lpParam = nullptr); bool CreateEx(uint32 dwExStyle, const char *lpszClassName, const char *lpszWindowName, uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID, void *lpParam = nullptr); /** * Gets a list of CWnd pointers for parent controls * up to the window. It only allows a single dialog * parent to be present, working around the issue * when modal dialogs create other modal dialogs. */ Common::Array GetSafeParents(bool includeSelf = true) const; Common::Array GetSafeParents(bool includeSelf = true); CWnd *GetParent() const; CWnd *GetTopLevelFrame(); HWND GetSafeHwnd() const; void ShowWindow(int nCmdShow); bool EnableWindow(bool bEnable = true); void UpdateWindow(); bool RedrawWindow( LPCRECT lpRectUpdate = nullptr, CRgn *prgnUpdate = nullptr, unsigned int flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN ); void SetActiveWindow(); void SetFocus(); CWnd *GetFocus() const; bool IsWindowVisible() const { return (GetStyle() & WS_VISIBLE) != 0; } void DestroyWindow(); void Invalidate(bool bErase = true); // Message processing for modeless dialog-like windows virtual bool IsDialogMessage(LPMSG lpMsg) { return false; } int GetWindowText(CString &rString) const; int GetWindowText(char *lpszStringBuf, int nMaxCount) const; bool SetWindowText(const char *lpszString); unsigned int GetState() const; uint32 GetStyle() const { return m_nStyle; } void SetStyle(uint32 nStyle); bool IsWindowEnabled() const { return (_itemState & ODS_DISABLED) == 0; } bool IsActiveWindow() const; CDC *GetDC(); int ReleaseDC(CDC *pDC); bool PostMessage(unsigned int message, WPARAM wParam = 0, LPARAM lParam = 0); LRESULT SendMessage(unsigned int message, WPARAM wParam = 0, LPARAM lParam = 0); void SendMessageToDescendants(unsigned int message, WPARAM wParam = 0, LPARAM lParam = 0, bool bDeep = true, bool bOnlyPerm = false); static void SendMessageToDescendants(HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam, bool bDeep, bool bOnlyPerm); bool Validate(); bool ValidateRect(LPCRECT lpRect = nullptr); bool InvalidateRect(LPCRECT lpRect, bool bErase = true); void GetWindowRect(LPRECT lpRect) const; bool GetUpdateRect(LPRECT lpRect, bool bErase = false); bool GetClientRect(LPRECT lpRect) const; RECT GetClientRect() const; bool PointInClientRect(const POINT &pt) const; void ClientToScreen(LPPOINT lpPoint) const; void ClientToScreen(LPRECT lpRect) const; void ScreenToClient(LPPOINT lpPoint) const; void ScreenToClient(LPRECT lpRect) const; RECT GetWindowRectInParentCoords() const; void MoveWindow(LPCRECT lpRect, bool bRepaint = true); void MoveWindow(int x, int y, int nWidth, int nHeight, bool bRepaint = true); HDC BeginPaint(LPPAINTSTRUCT lpPaint); bool EndPaint(const PAINTSTRUCT *lpPaint); CWnd *GetDlgItem(int nID) const; CWnd *GetNextDlgGroupItem(CWnd *pWndCtl, bool bPrevious = false) const; bool GotoDlgCtrl(CWnd *pWndCtrl); bool SubclassDlgItem(unsigned int nID, CWnd *pParent); bool SetDlgItemText(int nIDDlgItem, const char *lpString); int GetDlgCtrlID() const; void CheckDlgButton(int nIDButton, unsigned int nCheck); LRESULT SendDlgItemMessage(int nID, unsigned int message, WPARAM wParam = 0, LPARAM lParam = 0) const; uintptr SetTimer(uintptr nIDEvent, unsigned int nElapse, void (CALLBACK *lpfnTimer)(HWND, unsigned int, uintptr, uint32) = nullptr); bool KillTimer(uintptr nIDEvent); virtual bool PreTranslateMessage(MSG *pMsg) { return false; } virtual int GetScrollPos() const { return 0; } int GetScrollPosition() const { return GetScrollPos(); } virtual int SetScrollPos(int nPos, bool bRedraw = true) { return 0; } virtual void GetScrollRange(int *lpMinPos, int *lpMaxPos) const {} void GetScrollRange(int /*nBar*/, int *lpMinPos, int *lpMaxPos) const { GetScrollRange(lpMinPos, lpMaxPos); } virtual void SetScrollRange(int nMinPos, int nMaxPos, bool bRedraw) {} void SetCapture(); void ReleaseCapture(); const Common::HashMap &getChildren() const { return _children; } bool IsWindowDirty() const { return !_updateRect.isEmpty(); } HFONT GetFont() const { return _hFont; } void SetFont(CFont *pFont, bool bRedraw = true); void pause(); }; class CFrameWnd : public CWnd { DECLARE_DYNCREATE(CFrameWnd) private: CString m_strTitle; unsigned int m_nIDHelp = 0; CView *m_pViewActive = nullptr; void ActivateFrame(int nCmdShow); void OnUpdateFrameTitle(bool bAddToTitle); CWnd *CreateView(CCreateContext *pContext, unsigned int nID); protected: bool PreCreateWindow(CREATESTRUCT &cCs) override { return true; } int OnCreate(LPCREATESTRUCT lpcs); int OnCreateHelper(LPCREATESTRUCT lpcs, CCreateContext *pContext); bool OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext); void OnActivate(unsigned int nState, CWnd *pWndOther, bool bMinimized) override; enum RepositionFlags { reposDefault = 0, reposQuery = 1, reposExtra = 2, reposNoPosLeftOver = 0x8000 }; bool RepositionBars( unsigned int nIDFirst, unsigned int nIDLast, unsigned int nIDLeftOver, unsigned int nFlag = reposDefault, LPRECT lpRectParam = nullptr, LPCRECT lpRectClient = nullptr, bool bStretch = true ); DECLARE_MESSAGE_MAP() public: ~CFrameWnd() override { } bool Create(const char *lpszClassName, const char *lpszWindowName, uint32 dwStyle, const RECT &rect, CWnd *pParentWnd = nullptr, const char *lpszMenuName = nullptr, uint32 dwExStyle = 0, CCreateContext *pContext = nullptr); bool Create(const char *lpszClassName, const char *lpszWindowName, uint32 dwStyle = WS_OVERLAPPEDWINDOW) { CRect rectDefault; return Create(lpszClassName, lpszWindowName, dwStyle, rectDefault); } HMENU GetMenu() const; void RecalcLayout(bool bNotify = true); void InitialUpdateFrame(CDocument *pDoc, bool bMakeVisible); bool LoadFrame(unsigned int nIDResource, uint32 dwDefaultStyle, CWnd *pParentWnd, CCreateContext *pContext); CView *GetActiveView() const; void SetActiveView(CView *pViewNew, bool bNotify = true); void OnSetFocus(CWnd *pOldWnd); CDocument *GetActiveDocument(); }; class CDialog : public CWnd { DECLARE_DYNAMIC(CDialog) friend class CDialogTemplate; private: const char *m_lpszTemplateName = nullptr; unsigned int m_nIDHelp = 0; LPCDLGTEMPLATE m_lpDialogTemplate = nullptr; HGLOBAL m_hDialogTemplate = 0; int _defaultId = 0; CFont _dialogFont; void SetParent(CWnd *wnd); bool CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd *pParentWnd, void *lpDialogInit, HINSTANCE hInst); bool CreateIndirect(HGLOBAL hDialogTemplate, CWnd *pParentWnd, HINSTANCE hInst); bool CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd *pParentWnd, HINSTANCE hInst); CButton *GetDefaultPushButton() const; bool handleEnterKey(LPMSG lpMsg); bool handleEscapeKey(LPMSG lpMsg); void sendButtonClicked(CButton *btn); protected: DECLARE_MESSAGE_MAP() virtual void OnOK(); virtual void OnCancel(); virtual void PostModal() { } void OnSysChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags); void OnActivate(unsigned int nState, CWnd *pWndOther, bool bMinimized) override; public: CDialog() {} explicit CDialog(const char *lpszTemplateName, CWnd *pParentWnd = nullptr); explicit CDialog(unsigned int nIDTemplate, CWnd *pParentWnd = nullptr); ~CDialog() override {} bool Create(const char *lpszTemplateName, CWnd *pParentWnd = nullptr); bool Create(unsigned int nIDTemplate, CWnd *pParentWnd = nullptr); int DoModal(); virtual void PreInitDialog() {} virtual bool OnInitDialog() { return true; } bool IsDialogMessage(LPMSG lpMsg) override; uint32 GetDefID() const; void SetDefID(unsigned int nID); LRESULT HandleInitDialog(WPARAM, LPARAM); LRESULT HandleSetFont(WPARAM, LPARAM); void AFXAPI DDX_Control(CDataExchange *pDX, int nIDC, CWnd &rControl); void AFXAPI DDX_Radio(CDataExchange *pDX, int nIDCButton1, int &value); void AFXAPI DDX_Text(CDataExchange *pDX, int nIDC, int &value); void AFXAPI DDX_Text(CDataExchange *pDX, int nIDC, CString &value); void AFXAPI DDX_Text(CDataExchange *pDX, int nIDC, unsigned int &value); void AFXAPI DDX_Text(CDataExchange *pDX, int nIDC, long &value); void AFXAPI DDX_Text(CDataExchange *pDX, int nIDC, double &value); void AFXAPI DDX_Check(CDataExchange *pDX, int nIDC, bool value); void AFXAPI DDV_MinMaxInt(CDataExchange *pDX, int value, int nMin, int nMax); // termination void EndDialog(int nResult); bool UpdateData(bool bSaveAndValidate = true); }; class CStatic : public CWnd { DECLARE_DYNAMIC(CStatic) protected: DECLARE_MESSAGE_MAP() public: ~CStatic() override { } }; class CButton : public CWnd { DECLARE_DYNAMIC(CButton) private: bool _pressed = false; void OnPushButtonPaint(); void OnPushBoxPaint(); void OnOwnerDrawPaint(); protected: DECLARE_MESSAGE_MAP() void OnPaint(); void OnLButtonDown(unsigned int nFlags, CPoint point); void OnLButtonUp(unsigned int nFlags, CPoint point); void OnMouseMove(unsigned int nFlags, CPoint point); LRESULT OnBnClicked(WPARAM wParam, LPARAM lParam); LRESULT OnBnSetCheck(WPARAM wParam, LPARAM lParam); public: ~CButton() override { } CVIRTUAL bool Create(const char *lpszCaption, uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID); int GetCheck() const; void SetCheck(int nCheck); void SetButtonStyle(unsigned int nStyle, bool bRedraw = true); unsigned int GetButtonStyle() const; }; class CListBox : public CWnd { DECLARE_DYNAMIC(CListBox) protected: DECLARE_MESSAGE_MAP() public: ~CListBox() override { } }; class CCheckListBox : public CListBox { DECLARE_DYNAMIC(CCheckListBox) public: ~CCheckListBox() override { } }; class CEdit : public CWnd { DECLARE_DYNAMIC(CEdit) private: size_t _maxLength = 0; bool _cursorVisible = false; protected: DECLARE_MESSAGE_MAP() public: ~CEdit() override { } CVIRTUAL bool Create(uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID); void LimitText(int nChars); void SetSel(int nStartChar, int nEndChar, bool bNoScroll = false); afx_msg void OnPaint(); afx_msg void OnKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags); afx_msg void OnChar(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags); afx_msg void OnSetFocus(CWnd *pOldWnd); afx_msg void OnKillFocus(CWnd *pNewWnd); afx_msg void OnTimer(uintptr nTimerId); afx_msg unsigned int OnGetDlgCode(); }; class CScrollBar : public CWnd { DECLARE_DYNAMIC(CScrollBar) private: int _minValue = 0; int _maxValue = 100; int _pageSize = 10; int _value = 0; void drawSquare(CPaintDC &dc, const CRect &r); void drawArrow(CPaintDC &dc, const CRect &r, bool leftArrow); CRect getThumbRect() const; int getIndexFromX(int xp) const; void scrollEvent(int action); protected: DECLARE_MESSAGE_MAP() void OnPaint(); void OnLButtonDown(unsigned int nFlags, CPoint point); void OnLButtonUp(unsigned int nFlags, CPoint point); void OnMouseMove(unsigned int, CPoint point); public: ~CScrollBar() override { } CVIRTUAL bool Create(uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID); int GetScrollPos() const override; int SetScrollPos(int nPos, bool bRedraw = true) override; void GetScrollRange(int *lpMinPos, int *lpMaxPos) const override; void SetScrollRange(int nMinPos, int nMaxPos, bool bRedraw) override; void ShowScrollBar(bool bShow); bool SetScrollInfo(LPSCROLLINFO lpScrollInfo, bool bRedraw); }; class CView : public CWnd { DECLARE_DYNAMIC(CView) protected: virtual bool PreCreateWindow(CREATESTRUCT &cCs) override; virtual void OnDraw(CDC *pDC) {} void OnPaint(); void OnNcDestroy(); DECLARE_MESSAGE_MAP() public: CDocument *m_pDocument = nullptr; public: ~CView() override { } int OnCreate(LPCREATESTRUCT lpcs); void OnDestroy(); void PostNcDestroy() override; void OnInitialUpdate(); virtual void OnUpdate(CView *pSender, LPARAM /*lHint*/, CObject * /*pHint*/); virtual void OnActivateView(bool, CView *, CView *) {} virtual void OnActivateFrame(unsigned int nState, CFrameWnd *pFrameWnd) {} CFrameWnd *GetParentFrame() const { return dynamic_cast(m_pParentWnd); } CDocument *GetDocument() const { return m_pDocument; } }; class CScrollView : public CView { DECLARE_DYNAMIC(CScrollView) private: static const SIZE sizeNull; protected: DECLARE_MESSAGE_MAP() public: ~CScrollView() override { } void SetScrollSizes( int nMapMode, SIZE sizeTotal, const SIZE &sizePage = sizeNull, const SIZE &sizeLine = sizeNull ); }; /*============================================================================*/ // class CDocTemplate creates documents class CDocTemplate : public CCmdTarget { DECLARE_DYNAMIC(CDocTemplate) private: unsigned int m_nIDResource = 0; const CRuntimeClass *m_pDocClass = nullptr; const CRuntimeClass *m_pFrameClass = nullptr; const CRuntimeClass *m_pViewClass = nullptr; protected: DECLARE_MESSAGE_MAP() CDocTemplate(unsigned int nIDResource, const CRuntimeClass *pDocClass, const CRuntimeClass *pFrameClass, const CRuntimeClass *pViewClass); public: /** * '\n' separated names * The document names sub-strings are represented as _one_ string: * windowTitle\ndocName\n ... (see DocStringIndex enum) */ CString m_strDocStrings; public: /** * Open named file * @param lpszPathName Path name. If null, * then create new file with this type */ virtual CDocument *OpenDocumentFile(const char *lpszPathName, bool bMakeVisible = true) = 0; virtual CDocument *CreateNewDocument(); virtual CFrameWnd *CreateNewFrame(CDocument *pDoc, CFrameWnd *pOther); virtual void SetDefaultTitle(CDocument *pDocument) = 0; virtual void InitialUpdateFrame(CFrameWnd *pFrame, CDocument *pDoc, bool bMakeVisible = true); virtual void AddDocument(CDocument *pDoc); // must override virtual void RemoveDocument(CDocument *pDoc); // must override virtual void CloseAllDocuments(bool bEndSession); virtual POSITION GetFirstDocPosition() const = 0; virtual CDocument *GetNextDoc(POSITION &rPos) const = 0; void LoadTemplate(); }; class CSingleDocTemplate : public CDocTemplate { DECLARE_DYNAMIC(CSingleDocTemplate) private: CDocument *m_pOnlyDoc = nullptr; public: DECLARE_MESSAGE_MAP() public: CSingleDocTemplate( unsigned int nIDResource, const CRuntimeClass *pDocClass, const CRuntimeClass *pFrameClass, const CRuntimeClass *pViewClass ) : CDocTemplate(nIDResource, pDocClass, pFrameClass, pViewClass) { } ~CSingleDocTemplate(); /** * Open named file * @param lpszPathName Path name. If null, * then create new file with this type */ CDocument *OpenDocumentFile(const char *lpszPathName, bool bMakeVisible = true) override; void AddDocument(CDocument *pDoc) override; void SetDefaultTitle(CDocument *pDocument) override; POSITION GetFirstDocPosition() const override; CDocument *GetNextDoc(POSITION &rPos) const override; }; typedef Libs::List CTemplateList; class CDocManager { private: CTemplateList pStaticList; bool bStaticInit = false; protected: CTemplateList m_templateList; public: virtual ~CDocManager() {} void AddDocTemplate(CDocTemplate *pTemplate); void OnFileNew(); void OnFileOpen(); virtual void CloseAllDocuments(bool bEndSession); }; /*============================================================================*/ templateclass CHandleMap; class CWinThread : public CCmdTarget { DECLARE_DYNAMIC(CWinThread) public: ~CWinThread() override { } }; class CWinApp : public CWinThread, public Libs::EventLoop { DECLARE_DYNAMIC(CWinApp) private: CWinApp *_priorWinApp; Libs::Resources _resources; Libs::Settings _settings; Gfx::Cursors _cursors; Gfx::Fonts _fonts; Graphics::Screen _screen; int m_nWaitCursorCount = 0; HCURSOR m_hcurWaitCursorRestore = nullptr; HCURSOR _currentCursor = nullptr; Common::FSNode _currentDirectory; CHandleMap *m_pmapHDC = nullptr; CHandleMap *m_pmapHGDIOBJ = nullptr; CHandleMap *m_pmapWnd = nullptr; protected: virtual bool InitInstance(); virtual int ExitInstance(); public: static CWinApp *_activeApp; int m_nCmdShow = SW_SHOWNORMAL; const char *m_lpCmdLine = ""; CWnd *m_pMainWnd = nullptr; CPalette _systemPalette; CPalette _currentPalette; CFont _defaultFont; CPen _defaultPen; CBrush _defaultBrush; MSG _currentMessage; CDocManager *m_pDocManager = nullptr; public: CWinApp(const char *appName = nullptr); ~CWinApp() override; /** * Main execution for MFC applications */ int Run(); virtual bool InitApplication(); virtual bool SaveAllModified(); void SetDialogBkColor(); HCURSOR LoadStandardCursor(const char *lpszCursorName); HCURSOR LoadCursor(const char *lpszResourceName); HCURSOR LoadCursor(unsigned int nIDResource); HCURSOR SetCursor(HCURSOR hCursor); void BeginWaitCursor(); void EndWaitCursor(); /** * Adds or remove a wait mouse cursor * @param nCode 0 => restore, 1=> begin, -1=> end */ void DoWaitCursor(int nCode) override; void AddDocTemplate(CDocTemplate *pTemplate); void CloseAllDocuments(bool bEndSession); unsigned int GetProfileInt(const char *lpszSection, const char *lpszEntry, int nDefault); void WriteProfileInt(const char *lpszSection, const char *lpszEntry, int nValue); CString GetProfileString(const char *lpszSection, const char *lpszEntry, const char *lpszDefault = nullptr) ; bool WriteProfileString(const char *lpszSection, const char *lpszEntry, const char *lpszValue); virtual void OnFileNew(); virtual void OnFileOpen(); virtual void OnFilePrintSetup() {} CHandleMap *afxMapHGDIOBJ(bool bCreate = false); CHandleMap *afxMapHDC(bool bCreate = false); CHandleMap *afxMapWnd(bool bCreate = false); void AfxUnlockTempMaps(); /*== ScummVM added functions ==*/ void setDirectory(const char *folder); void setPalette(const Graphics::Palette &pal); byte getColor(COLORREF color) const; Graphics::Screen *getScreen() { return &_screen; } // resource functions /** * Adds a Windows file containing resources */ void addResources(const Common::Path &file) { _resources.addResources(file); } void removeResources(const Common::Path &file) { _resources.removeResources(file); } HRSRC findResource(const char *lpName, const char *lpType); size_t sizeofResource(HRSRC hResInfo); HGLOBAL loadResource(HRSRC hResInfo); void *lockResource(HGLOBAL hResData); void unlockResource(HGLOBAL hResData); bool freeResource(HGLOBAL hResData); const Libs::Resources &getResources() const { return _resources; } // Fonts int addFontResource(const char *fontName) { return _fonts.addFontResource(fontName); } bool removeFontResource(const char *fontName) { return _fonts.removeFontResource(fontName); } HFONT createFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int nWeight, byte bItalic, byte bUnderline, byte cStrikeOut, byte nCharSet, byte nOutPrecision, byte nClipPrecision, byte nQuality, byte nPitchAndFamily, const char *lpszFacename) { return _fonts.createFont(nHeight, nWidth, nEscapement, nOrientation, nWeight, bItalic, bUnderline, cStrikeOut, nCharSet, nOutPrecision, nClipPrecision, nQuality, nPitchAndFamily, lpszFacename); } HFONT getFont(const char *lpszFacename, int nHeight); HFONT getDefaultFont() { assert(_defaultFont.m_hObject); return (HFONT)_defaultFont.m_hObject; } HPEN getDefaultPen() const { assert(_defaultPen.m_hObject); return (HPEN)_defaultPen.m_hObject; } HBRUSH getDefaultBrush() { assert(_defaultBrush.m_hObject); return (HBRUSH)_defaultBrush.m_hObject; } HPALETTE getCurrentPalette() const { assert(_currentPalette.m_hObject); return (HPALETTE)_currentPalette.m_hObject; } HPALETTE getSystemDefaultPalette() const { assert(_systemPalette.m_hObject); return (HPALETTE)_systemPalette.m_hObject; } const char *AfxRegisterWndClass(unsigned int nClassStyle, HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon); bool GetClassInfo(HINSTANCE hInstance, const char * lpClassName, LPWNDCLASS lpWndClass); }; } // namespace MFC } // namespace Bagel #endif