首页 新闻 会员 周边

C++问题:windows程序设计关于创建窗口的问题

0
悬赏园豆:100 [已解决问题] 解决于 2015-06-01 21:02

  新人自学Windows程序设计,照着网上找的视频教程把一些API函数封装了一下,结果显示的跟说好的不一样。本来应该创建一个Button按钮,结果却没有显示,求指导。

  本人初学顾没什么重点,所以废话比较多,并且只好将能贴出来的代码都贴出来,为了节省版面一些头文件和声明什么的都没贴出来,程序中几乎所有的接口函数都是虚函数。

  关于消息循环的概念基本没有,只是依葫芦画瓢,教程怎么说我就怎么写,个人关于这个程序的理解是这样的:

1.入口函数里的InitInstance由于虚函数多态性调用到QDemoWinApp中的InitInstance;

2.在QDemoWinApp中的InitInstance中用QMainFrame产生一个对象并通过这个对象调用该对象基类QWnd中的CreateEx来注册和创建窗口;

3.完了之后在CreateEx中自己发送一个WM_CREATE,由于自己封装了一个新的回调函数,顾调用到派生类QMainFrame中的OnCreate从而调用到QButton中CreateEx创建一个BUTTON(结果却没创建)

程序如下:

int WINAPI _tWinMain(IN HINSTANCE hInstance,IN HINSTANCE hPreInstance,IN LPTSTR lpCmdLine,IN int nShowCmd)
{
    
    QWinApp* pWinApp = GlbGetApp();
    assert(pWinApp);
    pWinApp->InitInstance();
    pWinApp->Run();
    pWinApp->ExitInstance();
    return TRUE;

}

QWinApp

QWinApp::QWinApp(void)
{
    m_pMainWnd = NULL;
    g_pWinApp = this;
}

QWinApp::~QWinApp(void)
{
}

BOOL QWinApp::InitInstance()
{
    return TRUE;
}
BOOL QWinApp::ExitInstance()
{
    return TRUE;
}
void QWinApp::Run()
{
    MSG msg;
    while(::GetMessage(&msg,NULL,NULL,NULL))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
}

QDemoWinApp

QDemoWinApp::QDemoWinApp(void)
{
}

QDemoWinApp::~QDemoWinApp(void)
{
}

QDemoWinApp theApp;

BOOL QDemoWinApp::InitInstance()
{
    
    QMainFrame* pMainWnd = new QMainFrame();
    assert(pMainWnd);

    m_pMainWnd = pMainWnd;

    BOOL bRet = pMainWnd ->CreateEx(0,_T("拓拓拓"),_T("拓拓拓"),WS_VISIBLE|WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL);
    if(!bRet)
    {
        ::MessageBox(NULL,_T("创建窗口失败"),_T("创建窗口"),0);
        return FALSE;
    }

    pMainWnd ->ShowWindow(SW_SHOW);
    pMainWnd ->UpdateWindow();
    return TRUE;
}
BOOL QDemoWinApp::ExitInstance()
{
    if(m_pMainWnd)
    {
        delete m_pMainWnd;
        m_pMainWnd = NULL;
    }
    return TRUE;
}

QWnd

  1 LRESULT CALLBACK QWnd::WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  2 {
  3     if(uMsg == WM_CREATE || uMsg == WM_NCCREATE)
  4     {
  5         LPCREATESTRUCT pCs = (LPCREATESTRUCT)lParam;
  6         if(pCs)
  7         {
  8             QWnd* pWnd = (QWnd*)pCs->lpCreateParams;
  9             if(pWnd)
 10             {
 11                 pWnd->m_hWnd = hWnd;
 12                 pWnd->m_lpfnOldWndProc = (WNDPROC)(LONG_PTR)GetWindowLong(hWnd,GWL_WNDPROC);
 13                 return pWnd->Windowproc(uMsg,wParam,lParam);
 14             }
 15         }
 16     }
 17 
 18     QWnd* pWnd = (QWnd*)(LONG_PTR)GetWindowLong(hWnd,GWL_USERDATA);
 19     if(pWnd)
 20     {
 21         return pWnd->Windowproc(uMsg,wParam,lParam);
 22     }
 23 
 24     return ::DefWindowProc(hWnd,uMsg,wParam,lParam);
 25     //return ::DefWindowProc(hWnd,uMsg,wParam,lParam);
 26 }
 27 
 28 LRESULT QWnd::Windowproc(UINT uMsg,WPARAM wParam,LPARAM lParam)
 29 {
 30     switch(uMsg)
 31     {
 32         case WM_CLOSE:
 33             {
 34                 return OnClose(wParam,lParam);
 35             }
 36             break;
 37         case WM_DESTROY:
 38             {
 39                 return OnDestroy(wParam,lParam);
 40             }
 41             break;
 42         case WM_CREATE:
 43             {
 44                 return OnCreate(wParam,lParam);
 45             }
 46             break;
 47         default:
 48             break;
 49     }
 50     return Default(uMsg,wParam,lParam);
 51 }
 52 
 53 LRESULT QWnd::Default(UINT uMsg,WPARAM wParam,LPARAM lParam)
 54 {
 55     if(m_lpfnOldWndProc==QWnd::WndProc)
 56     {
 57         return ::DefWindowProc(m_hWnd,uMsg,wParam,lParam);
 58     }
 59 
 60     return m_lpfnOldWndProc(m_hWnd,uMsg,wParam,lParam);
 61 }
 62 
 63 //msg
 64 LRESULT QWnd::OnClose(WPARAM wParam,LPARAM lParam)
 65 {
 66     return Default(WM_CLOSE,wParam,lParam);
 67 }
 68 
 69 LRESULT QWnd::OnDestroy(WPARAM wParam,LPARAM lParam)
 70 {
 71     return Default(WM_DESTROY,wParam,lParam);
 72 }
 73 
 74 LRESULT QWnd::OnCreate(WPARAM wParam,LPARAM lParam)
 75 {
 76     return Default(WM_CREATE,wParam,lParam);
 77 }
 78 
 79 QWnd::QWnd(void)
 80 {
 81     m_hWnd = NULL;
 82     m_lpfnOldWndProc = NULL;
 83 }
 84 
 85 QWnd::~QWnd(void)
 86 {
 87 }
 88 
 89 BOOL QWnd::PreCreateWindow(CREATESTRUCT& cs)
 90 {
 91     
 92     WNDCLASSEX wcex;
 93     wcex.cbSize = sizeof(WNDCLASSEX);
 94     BOOL bRet = ::GetClassInfoEx(cs.hInstance,cs.lpszClass,&wcex);
 95     if(bRet)
 96     {
 97         return TRUE;
 98     }
 99         /*注册窗口*/
100     
101     wcex.style  =CS_HREDRAW | CS_VREDRAW;
102     wcex.lpfnWndProc = WndProc;
103     wcex.cbClsExtra = 0;
104     wcex.cbWndExtra = 0;
105     wcex.hInstance  = cs.hInstance;
106     wcex.hIcon = (HICON)::LoadIcon(NULL,IDI_APPLICATION);
107     wcex.hIconSm = (HICON)::LoadIcon(NULL,IDI_APPLICATION);
108     wcex.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
109     wcex.hCursor = (HCURSOR)::LoadCursor(NULL,IDC_ARROW);
110     wcex.lpszMenuName = NULL;
111     wcex.lpszClassName = cs.lpszClass;
112     bRet = ::RegisterClassEx(&wcex);
113     if(!bRet)
114     {
115         ::MessageBox(NULL,_T("窗口注册失败"),_T("注册窗口"),0);
116         return FALSE;
117 
118     }
119     return TRUE;
120 
121 }
122 
123 
124 BOOL QWnd::CreateEx(
125             DWORD dwExStyle,
126             LPCTSTR lpszClassName,
127             LPCTSTR lpszWindowName,
128             DWORD dwStyle,
129             int x,
130             int y,
131             int nWidth,
132             int nHeight,
133             HWND hWndParent,
134             HMENU nIDorHMenu,
135             LPVOID lpParam
136                         )
137 {
138     HINSTANCE hInstance = (HINSTANCE)::GetModuleHandle(NULL);
139     assert(hInstance);
140     CREATESTRUCT cs;
141     cs.cx = nWidth;
142     cs.cx = nHeight;
143     cs.dwExStyle = dwExStyle;
144     cs.hInstance = hInstance;
145     cs.hMenu = nIDorHMenu;
146     cs.hwndParent = hWndParent;
147     cs.lpCreateParams = lpParam;
148     cs.lpszClass = lpszClassName;
149     cs.lpszName = lpszWindowName;
150     cs.style = dwStyle;
151     cs.x = x;
152     cs.y = y;
153 
154     BOOL bRet = PreCreateWindow(cs);
155     if(!bRet)
156     {
157         ::MessageBox(NULL,_T("注册窗口类失败"),_T("注册窗口"),0);
158         return FALSE;
159     }
160 
161     HWND hWnd = ::CreateWindowEx(cs.dwExStyle,cs.lpszClass,cs.lpszName,cs.style,cs.x,cs.y,
162         cs.cx,cs.cy,cs.hwndParent,cs.hMenu,cs.hInstance,this);
163     if(NULL == hWnd)
164     {
165         return FALSE;
166     }
167     m_hWnd = hWnd;
168     SetWindowLong(m_hWnd,GWL_USERDATA,(LONG)(LONG_PTR)this);
169 
170     m_lpfnOldWndProc = (WNDPROC)(LONG_PTR)GetWindowLong(m_hWnd,GWL_WNDPROC);
171     if(m_lpfnOldWndProc != QWnd::WndProc)
172     {
173         // 子类化
174         SetWindowLong(m_hWnd,GWL_WNDPROC,(long)QWnd::WndProc);
175         Windowproc(WM_CREATE,0,0);
176         Windowproc(WM_NCCREATE,0,0);
177     }
178     return TRUE;
179 }
180 
181 BOOL QWnd::ShowWindow(int nCmdShow)
182 {
183     assert(m_hWnd);
184     return ::ShowWindow(m_hWnd,nCmdShow);
185 }
186 BOOL QWnd::UpdateWindow()
187 {
188     
189     assert(m_hWnd);
190     return ::UpdateWindow(m_hWnd);
191 
192 }
193 BOOL QWnd::DestroyWindow()
194 {
195     assert(m_hWnd);
196     return ::DestroyWindow(m_hWnd);
197 
198 }
QWnd.cpp

QMainFrame

QMainFrame::QMainFrame(void)
{
}

QMainFrame::~QMainFrame(void)
{
}


//msg
LRESULT QMainFrame::OnClose(WPARAM wParam,LPARAM lParam)
{
    return DestroyWindow();
}

LRESULT QMainFrame::OnDestroy(WPARAM wParam,LPARAM lParam)
{
    PostQuitMessage(0);
    return TRUE;
}

LRESULT QMainFrame::OnCreate(WPARAM wParam,LPARAM lParam)
{
    if(NULL==m_wndButton.m_hWnd)
    {
        m_wndButton.CreateEx(_T(""),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,0,0,200,120,m_hWnd,(HMENU)IDC_BUTTON);
    }
    return TRUE;
}

QButton

QButton::QButton(void)
{
}

QButton::~QButton(void)
{
}

BOOL QButton::CreateEx(            
                        LPCTSTR lpszWindowName,
                        DWORD dwStyle,
                        int x,
                        int y,
                        int nWidth,
                        int nHeight,
                        HWND hWndParent,
                        HMENU nIDorHMenu            
                        )
{
    return QWnd::CreateEx(0,_T("BUTTON"),lpszWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,nIDorHMenu);
}
tangshaotuo的主页 tangshaotuo | 初学一级 | 园豆:112
提问于:2015-05-30 13:46
< >
分享
最佳答案
0

首先,针对楼主的代码,在回调函数中(Windowproc)添加一个WM_PAINT消息,这是进行一些绘制工作的消息,在此消息下进行按钮的创建,并获取父窗口的句柄,将该按钮添加到该句柄上就可以啦,对于楼主说的消息循环机制,楼主可以这样理解,一个Win32程序如果想在屏幕上持续显示是需要进行死循环才可以的,对应楼主的代码就是Run函数啦,建议楼主还是了解一些Win32程序的运行机制,我只能帮你到这啦!

收获园豆:100
hippieZhou | 小虾三级 |园豆:578 | 2015-05-31 10:23
其他回答(1)
0

QT?

[0] | 园豆:1257 (小虾三级) | 2015-05-30 14:36

没学过QT,QT不是应该把接口都封装好了吗

支持(0) 反对(0) tangshaotuo | 园豆:112 (初学一级) | 2015-05-30 14:41

@tangshaotuo: 这个我就不晓得了。

支持(0) 反对(0) [0] | 园豆:1257 (小虾三级) | 2015-05-30 14:47
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册