1创建应用的一般流程
来源:互联网 发布:如何进入人工智能行业 编辑:程序博客网 时间:2024/04/28 07:43
0.duilib创建应用的一般流程
- 为应用分配一个实例
- 新建窗口 (注册窗口类及窗口过程、create窗口)
- 窗口配置(去掉标题栏,设置位置及大小)
- 展示窗口
- 消息循环
1.初始化必要的信息
CPaintManagerUI::SetInstance(hInstance); //设置实例对象,对应于应用实例CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); //资源路径(图片、文字等)
2.窗口创建
MainFrame* pFrame = new MainFrame();pFrame->Create(NULL, _T("window name"), UI_WNDSTYLE_FRAME, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 0, 0, 600, 800);
其中create()在CWindowWnd实现,其注册窗口类,并调用系统的CreateWindowEx()创建窗口。
HWND CWindowWnd::Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x, int y, int cx, int cy, HMENU hMenu){ if( GetSuperClassName() != NULL && !RegisterSuperclass() ) return NULL; if( GetSuperClassName() == NULL && !RegisterWindowClass() ) return NULL; m_hWnd = ::CreateWindowEx(dwExStyle, GetWindowClassName(), pstrName, dwStyle, x, y, cx, cy, hwndParent, hMenu, CPaintManagerUI::GetInstance(), this); ASSERT(m_hWnd!=NULL); return m_hWnd;}
3.注册窗口类
bool CWindowWnd::RegisterWindowClass(){ WNDCLASS wc = { 0 }; wc.style = GetClassStyle(); wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hIcon = NULL; wc.lpfnWndProc = CWindowWnd::__WndProc; wc.hInstance = CPaintManagerUI::GetInstance(); wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = GetWindowClassName(); ATOM ret = ::RegisterClass(&wc); ASSERT(ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS); return ret != NULL || ::GetLastError() == ERROR_CLASS_ALREADY_EXISTS;}
4.窗口过程
在窗口创建之前,即WM_NCCREATE消息时,将CWindowWnd对象指针保存在GWLP_USERDATA中,在处理其他消息中,利用此分别调用不同窗口的处理函数:pThis->HandleMessage(uMsg, wParam, lParam)
继承CWindowWnd的窗口可以通过实现HandleMessage()函数从而个性化处理各种消息。
LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ CWindowWnd* pThis = NULL; if( uMsg == WM_NCCREATE ) { LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams); pThis->m_hWnd = hWnd; ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(pThis)); } else { pThis = reinterpret_cast<CWindowWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); if( uMsg == WM_NCDESTROY && pThis != NULL ) { LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam); ::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L); if( pThis->m_bSubclassed ) { pThis->Unsubclass(); } pThis->m_hWnd = NULL; pThis->OnFinalMessage(hWnd); return lRes; } } if( pThis != NULL ) { return pThis->HandleMessage(uMsg, wParam, lParam); } else { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); }}
5.消息循环
CPaintManagerUI::MessageLoop();
具体实现如下:
void CPaintManagerUI::MessageLoop(){ MSG msg = { 0 }; while( ::GetMessage(&msg, NULL, 0, 0) ) { if( !CPaintManagerUI::TranslateMessage(&msg) ) { ::TranslateMessage(&msg); try { ::DispatchMessage(&msg); } catch(...) { DUITRACE(_T("EXCEPTION: %s(%d)\n"), __FILET__, __LINE__); #ifdef _DEBUG throw "CPaintManagerUI::MessageLoop"; #endif } } }}
后面会对消息循环进行详细解析,现在仅将CPaintManagerUI::TranslateMessage(&msg)函数的实现简介如下:
bool CPaintManagerUI::TranslateMessage(const LPMSG pMsg){ //1.当窗口有父窗口时,循环搜索当前的hwnd所以对应的窗口或其长辈窗口(父窗口、祖父窗口); //2.当窗口无父窗口时,循环搜索当前的hwnd所以对应的窗口; //如果找到,则处理;否则直接返回false CPaintManagerUI* pT = static_cast<CPaintManagerUI*>(m_aPreMessages[i]); if (pT->TranslateAccelerator(pMsg)) return true; if( pT->PreMessageHandler(pMsg->message, pMsg->wParam, pMsg->lParam, lRes) ) return true; return false;}
6.总结
将duilib中的 WinMain 函数的主要内容粘贴如下:
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow){ CPaintManagerUI::SetInstance(hInstance); CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); HINSTANCE hInstRich = ::LoadLibrary(_T("Riched20.dll"));//字符编辑器相关文件 MainFrame* pFrame = new MainFrame(); if( pFrame == NULL ) return 0; pFrame->Create(NULL, _T("QQ2011"), UI_WNDSTYLE_FRAME, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 0, 0, 600, 800); pFrame->CenterWindow(); ::ShowWindow(*pFrame, SW_SHOW); CPaintManagerUI::MessageLoop(); //一直在这里循环,除非执行退出命令 CPaintManagerUI::Term(); ::FreeLibrary(hInstRich); return 0;}
0 0
- 1创建应用的一般流程
- ThinkPHP创建应用的一般开发流程及实例
- ThinkPHP创建应用的一般开发流程及实例
- ThinkPHP创建应用的一般开发流程及实例
- 开发应用的一般流程(个人)
- OpenGL 一般程序创建流程
- Android应用一般上架流程
- Android应用一般上架流程
- 平面设计的一般流程
- 工业设计的一般流程
- 项目的一般流程
- 平面设计的一般流程
- 平面设计的一般流程
- 软件设计的一般流程
- pushlet的一般流程
- Hive创建表一般流程(优化)
- ajax一般的应用
- 黑客攻击的一般流程
- C语言系列(六)结构体和联合体
- 几种数据库连接池的用法
- RStudio 中的 R Markdown
- 洛谷 1576 最小花费
- POSIX.1 and ISO C标准头文件
- 1创建应用的一般流程
- 想不到app还可以这么玩(转载)
- spring注解注入
- && 和 ||
- Java后台工程师面试杂记——不跳不涨工资星人跳槽经历(转)
- 自定义图片视图的坑
- Java堆内存
- 8.25疑难解答
- ecm 面向连接电子模型开发工具包