Win32 C在类中创建窗口和过程

前端之家收集整理的这篇文章主要介绍了Win32 C在类中创建窗口和过程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
前文/问题

我试图做一个相当简单的工具来帮助调试变量值.因为它是完全自我包含在课堂内是我的目标.最终产品我可以在类中使用ShowThisValue(无论如何)中的函数.

我遇到的问题是,如果可能的话,我无法弄清楚课程内的程序.这是短版本,有问题.

-Code再次更新11/29 / 13-
– 我现在把它放在自己的项目中.

[main.cpp中]

viewvars TEST; // global
TEST.CreateTestWindow(hThisInstance); // in WinMain() right before ShowWindow(hwnd,nFunsterStil);

[viewvars.h]整个更新

class viewvars {

private:
    HWND hWindow;            // the window,a pointer to
    LRESULT WindowProc(UINT message,WPARAM wParam,LPARAM lParam);        
    static LRESULT CALLBACK ThisWindowProc(HWND hwnd,UINT message,LPARAM lParam);

public:        
    viewvars(); // blank constructor
    int CreateTestWindow(HINSTANCE hInst);

};

// blank constructor
viewvars::viewvars() {}



// create the window
int viewvars::CreateTestWindow(HINSTANCE hInst) {

// variables
char thisClassName[] = "viewVars";     
MSG msg;       
WNDCLASS wincl;  


// check for class info and modify the info
if (!GetClassInfo(hInst,thisClassName,&wincl)) {
    wincl.style = 0;
    wincl.hInstance = hInst;
    wincl.lpszClassName = thisClassName;
    wincl.lpfnWndProc = &ThisWindowProc;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hIcon = NULL;
    wincl.hCursor = NULL;
    wincl.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
    wincl.lpszMenuName = NULL;

    if (RegisterClass(&wincl) == 0) {
        MessageBox(NULL,"The window class Failed to register.","Error",0); 
        return -1;
    }
}  

// create window
hWindow = CreateWindow(thisClassName,"Test",WS_POPUP | WS_CLIPCHILDREN,10,200,NULL,hInst,this);
if (hWindow == NULL) { 
    MessageBox(NULL,"Problem creating the window.",0); 
    return -1; 
} 

// show window
ShowWindow(hWindow,TRUE);

// message loop
while (GetMessage(&msg,hWindow,0))
{
    TranslateMessage(&msg);  
    DispatchMessage(&msg); 
}    

// then quit window?
DestroyWindow(hWindow);
hWindow = NULL;

return msg.wParam;
}   


// window proc
LRESULT CALLBACK viewvars::ThisWindowProc(HWND hwnd,LPARAM lParam) {

MessageBox(NULL,"Has it gone this far?","Bench",0); 

// variable
viewvars *view;

// ????
if (message == WM_NCCREATE) {
    CREATESTRUCT *cs = (CREATESTRUCT*)lParam; 
    view = (viewvars*) cs->lpCreateParams;

    SetLastError(0);
    if (SetWindowLongPtr(hwnd,GWL_USERDATA,(LONG_PTR) view) == 0) {
        if (GetLastError() != 0) {
            MessageBox(NULL,"There has been an error near here.",0); 
            return FALSE;
        }
    }
}
else {
    view = (viewvars*) GetWindowLongPtr(hwnd,GWL_USERDATA);
}


if (view) return view->WindowProc(message,wParam,lParam);

MessageBox(NULL,"If shown,the above statement did not return,and the statement below did.",0); 

return DefWindowProc(hwnd,message,lParam);
}


LRESULT viewvars::WindowProc(UINT message,LPARAM lParam) {
// you can access non-static members in here...
MessageBox(NULL,"Made it to window proc.",0);

switch (message)
{
    case WM_PAINT: 
        return 0;
    break;
    case WM_DESTROY:
        PostQuitMessage(0);       
        return 0;
    break;
    default:
        MessageBox(NULL,"DefWindowProc Returned.",0);
        return DefWindowProc(hWindow,lParam);
    break;
}
}

消息框按照以下顺序显示

有没有这样呢?
>使其进行窗口处理
>返回DefWindowProc
有没有这样呢? // 重复?
>使其进行窗口处理
>返回DefWindowProc
>创建窗口的问题

感谢您的帮助到目前为止.你知道问题在哪里吗?

主消息循环不能在您的类中,特别是不在“CreateTestWindow”函数中,因为您的线程将收到使GetMessage返回0的WM_QUIT消息之前不会从该函数返回.

这是您的viewvars类的简单实现.关键点:

> Window Proc是一个静态成员.
> Window Proc和对象之间的链接是通过
使用GWLP_USERDATA.见SetWindowLongPtr.
> DTOR类破坏窗口,如果它仍然存在. WM_DESTROY
消息将HWND成员设置为0.
>将OnMsgXXX方法添加到类很简单:declare / define then
并且只需使用“this”指针从WindowProc调用它们
存储在GWLP_USERDATA中.

编辑:

>根据陈先生的建议,HWND早期绑定到对象(在WM_NCCREATE中),以便在窗口创建期间允许消息处理程序作为方法.

我改变了创作风格,展现了窗口,并能够移动它.

// VIEWVARS.H
class viewvars {

public:
    static viewvars* CreateTestWindow( HINSTANCE hInstance );
    viewvars() : m_hWnd( 0 ) {}
    ~viewvars();

private:
    static LRESULT CALLBACK WindowProc( HWND hwnd,UINT uMsg,LPARAM lParam );
    static const char * m_pszClassName;
    HWND m_hWnd;

};

// VIEWVARS.CPP
#include "viewvars.h"

const char * viewvars::m_pszClassName = "viewvars";

viewvars * viewvars::CreateTestWindow( HINSTANCE hInst ) {

    WNDCLASS wincl;
    if (!GetClassInfo(hInst,m_pszClassName,&wincl)) {
        wincl.style = 0;
        wincl.hInstance = hInst;
        wincl.lpszClassName = m_pszClassName;
        wincl.lpfnWndProc = WindowProc;
        wincl.cbClsExtra = 0;
        wincl.cbWndExtra = 0;
        wincl.hIcon = NULL;
        wincl.hCursor = NULL;
        wincl.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
        wincl.lpszMenuName = NULL;
        if (RegisterClass(&wincl) == 0) {
            MessageBox(NULL,0);
            return 0;
        }
    }

    viewvars * pviewvars = new viewvars;
    HWND hWnd = CreateWindow( m_pszClassName,WS_VISIBLE | WS_OVERLAPPED,50,pviewvars );
    if ( hWnd == NULL ) {
        delete pviewvars;
        MessageBox(NULL,0); 
        return 0; 
    }

    return pviewvars;

}

 LRESULT CALLBACK viewvars::WindowProc( HWND hwnd,LPARAM lParam ) {

    switch ( uMsg ) {

        case WM_NCCREATE: {
            CREATESTRUCT * pcs = (CREATESTRUCT*)lParam;
            viewvars * pviewvars = (viewvars*)pcs->lpCreateParams;
            pviewvars->m_hWnd = hwnd;
            SetWindowLongPtr( hwnd,GWLP_USERDATA,(LONG)pcs->lpCreateParams );
            return TRUE;
        }

        case WM_DESTROY: {
            viewvars * pviewvars = (viewvars *)GetWindowLongPtr( hwnd,GWLP_USERDATA );
            if ( pviewvars ) pviewvars->m_hWnd = 0;
            break;
        }

        default:
            return DefWindowProc( hwnd,uMsg,lParam );

    }

    return 0;

}

viewvars::~viewvars() {
    if ( m_hWnd ) DestroyWindow( m_hWnd );
}

最后,一个“主要”的样本,但请注意,这里没有办法结束这个过程.应该通过常规代码(另一个窗口)来关注.

// MAIN.CPP
#include <Windows.h>
#include "viewvars.h"

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR    lpCmdLine,int       nCmdShow)
{
    viewvars * pviewvars = viewvars::CreateTestWindow( hInstance );
    if ( pviewvars == 0 ) return 0;

    BOOL bRet;
    MSG msg;
    while( (bRet = GetMessage( &msg,0 )) != 0)
    { 
        if (bRet == -1)
        {
            // handle the error and possibly exit
        }
        else
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
    }

    delete pviewvars;

    return 0;

}

猜你在找的Windows相关文章