Application type | describe |
---|---|
sdi | Single text |
Multithreaded sdi | One process, multiple windows |
mdi | Frame, multi window |
dialogue | Dialog based |
Multithreaded sdi new sdi windows and applications can be used as com servers Rebar bars are containers for toolbars, etc The command bar adds a window to the toolbar With rebar, press the toolbar to realize the toolbar and menu In this way, the menu also has associated icons
Optional visual:
regard | describe |
---|---|
Simple window | Process WM_PAINT, when drawing directly |
form | With dialog template, application operation |
list box | String can be added |
Edit box | Here's your editor |
List view | Such as control panel |
Tree vision | For hierarchical relationships, |
Rich text | Rich text |
Program thread
Same as atl, there is one_ Module, which is the instance of cappmodule / csserverappmodule (COM) The application has 1 / multiple ui threads Single ui calls global Run
int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT) { CMessageLoop theLoop; _Module.AddMessageLoop(&theLoop); CMainFrame wndMain; if (wndMain.CreateEx() == NULL) { ATLTRACE(_T("Failed to create main window")); return 0; } wndMain.ShowWindow(nCmdShow); int nRet = theLoop.Run(); _Module.RemoveMessageLoop(); return nRet; }
Loop messages within CMessageLoop Put into the global message mapping group Index by thread There are filter messages / idle processing, and interface elements can have their own idle processing Add yourself to the processor array of the message loop Run contains the main message mapping:
MSG m_msg; int CMessageLoop::Run() { for (;;) { while (!::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE)) DoIdleHandlers();//free bRet = ::GetMessage(&m_msg, NULL, 0, 0); if(bRet == -1)continue; else if(!bRet)break; if (!DoMessageFilters(&m_msg)) { ::TranslateMessage(&m_msg); ::DispatchMessage(&m_msg); }//distribute } return (int)m_msg.wParam; }
For multi interface threads, use wtl's thread manager
int nRet = m_dwCount; DWORD dwRet; while(m_dwCount > 0) { dwRet = ::MsgWaitForMultipleObjects(m_dwCount, m_arrThreadHandles, FALSE, INFINITE, QS_ALLINPUT); if(dwRet >= WAIT_OBJECT_0 && dwRet <= (WAIT_OBJECT_0 + m_dwCount - 1)) RemoveThread(dwRet - WAIT_OBJECT_0);//Delete thread else if(dwRet == (WAIT_OBJECT_0 + m_dwCount)) { ::GetMessage(&msg, NULL, 0, 0); if(msg.message == WM_USER) AddThread(_T(""), SW_SHOWNORMAL);//Add a thread and start it } }
WM received / thread removed_ When the user message, disconnect the wait You can also add your own message processor to the pipeline When there are multiple window types, to create a window, you only need any window to execute
::PostThreadMessage(_Module.m_dwMainThreadID, WM_USER, 0, 0L);
Interface thread, there is a thread process The conduit uses MsgWaitForMultipleObjects, so the maximum is used_ WAIT_ Objects (64) thread, up to 63 windows
frame
wtl, two types of windows: frame / view window The frame provides title bar / border, code processing toolbar / menu The view is the customer area
Thread creates the main frame in WM_CREATE view in create sdi has a view class. Just call to create it
mdi, create a window called MDICLIENT in cmdiframewindowimpl < >: createmdiclient() Take cmdichildwindowimpl < > as a sub window (with view), that is, mdi has 1 / multiple windows (with border / title bar, etc.)
LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL&) { //Create toolbar (command bar) HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE); //Framed menu (toolbar menu) m_CmdBar.AttachMenu(GetMenu()); //Add Icon m_CmdBar.LoadImages(IDR_MAINFRAME); //Delete the old menu, SetMenu(NULL); HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE); CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);//Toolbar, associating to the command bar AddSimpleReBarBand(hWndCmdBar); //Reinforcing bar It's a container, a command bar, a toolbar AddSimpleReBarBand(hWndToolBar, NULL, TRUE); CreateSimpleStatusBar(); m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,WS_EX_CLIENTEDGE);//Handle UIAddToolBar(hWndToolBar);//Runtime change UISetCheck(ID_VIEW_TOOLBAR, 1); UISetCheck(ID_VIEW_STATUS_BAR, 1); CMessageLoop* pLoop = _Module.GetMessageLoop(); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this);//Two filters return 0; } class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>, public CMessageFilter, public CIdleHandler //Main frame
Cupdateui < > supports updating interface mapping
view
class CMyView : public CWindowImpl<CMyView> { public: DECLARE_WND_CLASS(NULL) BOOL PreTranslateMessage(MSG* pMsg) { pMsg;return FALSE; } BEGIN_MSG_MAP(CMyView) MESSAGE_HANDLER(WM_PAINT, OnPaint) END_MSG_MAP() LRESULT OnPaint(UINT, WPARAM, LPARAM, BOOL&) { CPaintDC dc(m_hWnd);//To do: add painting code return 0; } };
Multithreaded sdi is similar to MDI, but there is no PreTranslateMessage method sdi uses it to distribute processing messages before framework processing, generally forwarding messages to view classes
To support mouse and keyboard, add corresponding message processing function to message mapping If you want to control based, add atlctrls h.
To add a scroll bar:
class CMyView : public CScrollWindowImpl<CMyView> { public: typedef CScrollWindowImpl<CMyView> parent; BEGIN_MSG_MAP(CMyView) CHAIN_MSG_MAP(parent)//On the chain END_MSG_MAP() void DoPaint(CDCHandle dc)//The function is changed {//Draw the entire view, not ` WM_PAINT` } };
To specify the scrolling range, size, or start point, you need to specify the scrolling range in WM_ Initialization in create
The frame window changes the size of the view window You can also use the splitter window to view trees and columns at the same time
You want to change the frame window to make the splitter window the view If there are:
CSplitterWindow m_view; CTreeViewCtrl m_tree; CListViewCtrl m_list;
When creating:
RECT rect; GetClientRect(&rect);//Take the customer area m_hWndClient = m_view.Create(m_hWnd, rect, NULL, WS_CHILD | WS_VISIBLE);//View create customer m_tree.Create(m_view, rcDefault, NULL,WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT,WS_EX_CLIENTEDGE);//Tree vision m_list.Create(m_view, rcDefault,NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT, WS_EX_CLIENTEDGE);//Column view m_view.SetSplitterPanes(m_tree, m_list); m_view.SetSplitterPos();//When there is no parameter, the center line is 0, which appears on the far left and hides the left window
Like the view, the splitter takes the frame as the parent window, and rcDefault can also be used In WM_ Adjust at size
After creating a splitter window, to create a sub window, use SetSplitterPanes to determine the position of the splitter bar
Update interface
Enable menu, tick mark, or single / multiple choice Menus can have icons and text It can be changed during operation The toolbar is just an externalization of the menu Therefore, it can be grouped effectively Specify which interfaces you want to update at runtime It is realized by updating the interface macro
BEGIN_UPDATE_UI_MAP(CMainFrame) UPDATE_ELEMENT(ID_FILE_SAVERESULTS, UPDUI_MENUPOPUP | UPDUI_TOOLBAR) UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP) UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP) END_UPDATE_UI_MAP()
wtl creates an array to hold this information
Change status:
term | command |
---|---|
Menu, toolbar button | UIEnable |
Tick | UISetCheck |
Menu text | UISetText |
Select in select | UISetRadio/UISetCheck |
For example:
BOOL bSelected = GetSelected();//condition //Whether text is selected UIEnable(ID_EDIT_CUT, bSelected);//Allow or not
It can be put into the corresponding processing function / OnIdle to check the class variables to determine the element state
Also determine whether they are all updated. Call a method of cupdateui < > to add the interface components to the list and have been automatically added to the main menu
Others add menus / toolbars through UIAddMenuBar() and UIAddToolBar()
After setting the toolbar status, use UIUpdateToolBar to update the status The menu does not have to be like this, because it generates sub menus dynamically Uiupdatemeubar is to restore the initial state
Uisetradio (multiple only single choice) is rarely used. You should code it yourself
dialog box
wtl adds input validation and callback functions For example, if you want to change the action when the user opens the folder in the dialog box, inherit from cfiledialogimpl < > and implement the OnFolderChange function
class CMyFileDialog : public CFileDialogImpl<CMyFileDialog> { public: CMyFileDialog(BOOL b) : CFileDialogImpl<CMyFileDialog>(b) { } void OnFolderChange(LPOFNOTIFY lpon) { char strFolder[MAX_PATH]; if (GetFolderPath(strFolder, sizeof(strFolder)) > 0)//Base class Take the path { MessageBox(strFolder); } } };
In this way, it is executed when changing the folder
control
WTL provides encapsulation classes for all Win32 and general controls
Two usage methods: if there is a control in the dialog box, attach the HWND of the control to the encapsulated object, use its method to access the control, simplify reading and writing control data and processing notification messages
2, Add class to the inheritance of view class
class CMyView : public CWindowImpl<CMyView, CListBox> //This window, inherited from CListBox,
Get the window class name with GetWndClassName The message will be sent to you. If it is not processed, it will be handled by the parent window
When an event occurs, most window controls send a notification to the parent window It is handled by the window If you want to process the button click, you only need to process BN_ The clicked notification is sent to the window class by the button Or inherit the button window from ccontainedwindow < > to handle click events Faster processing of notification messages and cumbersome inheritance
wtl also provides a command bar Other useful classes:
class | describe |
---|---|
CBitmapButton | Instead of the title, bitmap can provide a list, which can be switched in normal state, failure, push and mouse falling on the button |
CHyperLink | Hyperlink, click to open the web page |
CWaitCursor | Wait during construction and restore during destruction |
CCheckListViewCtrl | Check the list box |
CMultiPaneStatusBarCtrl | Multi panel status bar |