======================================CWnd.h=====================================#ifndef CWND_H
#define CWND_H#include<windows.h>
class CWnd
{
public:
CWnd(HWND Temp=NULL):m_hWnd(Temp){}
BOOL CreateWindowEx(
                DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
                        ); BOOL ShowWindow( HWND hWnd, int nCmdShow);
BOOL UpdateWindow( HWND hWnd );public: HWND m_hWnd;};BOOL CWnd::CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
{
m_hWnd=::CreateWindowEx(dwExStyle, lpClassName,lpWindowName,  dwStyle,  x, y,  nWidth,  nHeight,  hWndParent, hMenu,  hInstance,  lpParam);
if(NULL==m_hWnd)
return false;
else
return true;
}BOOL CWnd::ShowWindow( int nCmdShow) 
{
return ::ShowWindow( m_hWnd,  nCmdShow);
}BOOL CWnd::UpdateWindow() 
{
return ::UpdateWindow( m_hWnd) ;
}#endif
========================================winmain.cpp================================#include"CWnd.h"
LRESULT CALLBACK WindowProc( HWND hwnd,  UINT uMsg, WPARAM wParam,LPARAM lParam );
int WINAPI WinMain(HINSTANCE hInstance,  HINSTANCE hPrevInstance,  LPSTR lpCmdLine,  int nCmdShow ) 
{
WNDCLASS wndclass;
wndclass.cbClsExtra =0;
wndclass.cbWndExtra =0;
wndclass.hbrBackground =(HBRUSH)COLOR_BACKGROUND;
wndclass.hCursor =LoadCursor(NULL,IDC_APPSTARTING);
wndclass.hIcon=NULL;
wndclass.hInstance =hInstance;
wndclass.lpszClassName =TEXT("First");
wndclass.lpszMenuName =NULL;
wndclass.style =CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc =WindowProc; RegisterClass(&wndclass); CWnd cwnd;
cwnd.CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("First"),TEXT("模拟CWnd类的封装"),WS_OVERLAPPEDWINDOW ,100,100,200,400,NULL,NULL,hInstance,NULL);
cwnd.ShowWindow(SW_SHOWNORMAL);
cwnd.UpdateWindow (); MSG msg;
BOOL bRet; while( (bRet = GetMessage( &msg, cwnd.m_hWnd, 0, 0 )) != 0)

if (bRet == -1)
{
MessageBox(cwnd.m_hWnd ,TEXT("ERROR"),TEXT("WRONG"),MB_OK);
}
else
{
TranslateMessage(&msg); 
DispatchMessage(&msg); 
}
} return (int)msg.wParam ;
}LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch(uMsg)
{
case WM_PAINT:
PAINTSTRUCT  ps;
HDC hdc;
hdc=BeginPaint(hwnd,&ps);
TextOut(hdc,0,50,TEXT("VC2005.net"), (int)strlen("VC2005.net"));
EndPaint(hwnd,&ps);
        break; case WM_LBUTTONDOWN:
MessageBox(hwnd,TEXT("mouse click"),TEXT("Myapplication"),MB_OK);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,TEXT("你是否要退出程序?"),TEXT("Myapplication"),MB_YESNO))
{
DestroyWindow(hwnd);
}
break; case WM_DESTROY:
PostQuitMessage(0);
break; default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;}

解决方案 »

  1.   

    那你就不要加载mfc头文件和库,否则会引起冲突.
      

  2.   

    #include<windows.h> 写windows 程序这好象是必须的吧,再没加其他的了
      

  3.   

    楼主请仔细看看你的程序:
    声明处:
    BOOL ShowWindow( HWND hWnd, int nCmdShow);
    BOOL UpdateWindow( HWND hWnd );
    实现处:
    BOOL CWnd::ShowWindow( int nCmdShow) 
    {
    return ::ShowWindow( m_hWnd,  nCmdShow);
    }BOOL CWnd::UpdateWindow() 
    {
    return ::UpdateWindow( m_hWnd) ;
    }
    //声明与实现不一致声明处改成:
    BOOL ShowWindow( int nCmdShow);
    BOOL UpdateWindow( );
      

  4.   

    谢谢   seu07201213(【东南】〖汪洋中的一片叶子〗)还有一点问题,程序退出后在进程中还存在,是哪出问题了?这并没有动态分配内存,类的析构用默认的应该可以吧,WM_CLOSE 和 WM_DESTROY 消息的处理函数也应该没问题吧?
      

  5.   

    消息循环写的有问题;
    GetMessage 返回 -1 时,提示错误,少了一个break;来退出消息循环......
    if (bRet == -1)
    {
    MessageBox(cwnd.m_hWnd ,TEXT("ERROR"),TEXT("WRONG"),MB_OK);
    break;
    }
      

  6.   

    MSDN上关于GetMessage()返回值If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer. To get extended error information, call GetLastError.
    为什么代码中GetMesage()会有返回 -1 呢?
      

  7.   

    当WM_CLOSE,DestroyWindow(hwnd);句柄没了
      

  8.   

    那怎么才能让下面的弹出来?
    MessageBox(cwnd.m_hWnd ,TEXT("ERROR"),TEXT("WRONG"),MB_OK);
      

  9.   

    程序退出了,弹不出来了.
    用MessageBox(NULL ,TEXT("ERROR"),TEXT("WRONG"),MB_OK);也是弹出立即关闭,因为进程退出
      

  10.   

    那如果不是因为关闭程序导致句柄无效,是因为其他错误导致的,而且又要显示错误原因,下面的代码要再添什么?if (bRet == -1)
    {
     break;
    }
      

  11.   

    最好退出,因为GetMessage出现异常返回-1,不break;会一直循环下去了......
      

  12.   

    最好退出,因为GetMessage出现异常返回-1,不break;会一直循环下去了......==========================================有点晕关闭程序导致句柄无效这是无法避免的,也就是说"GetMessage出现异常返回-1"也是无法避免的
      

  13.   

    SDK示例工程一般是这样写的:
    while (GetMessage(&msg, NULL, 0, 0)) //这样就避免了上面的情况,这下清楚了吧
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }BOOL GetMessage(
      LPMSG lpMsg,         // address of structure with message
      HWND hWnd,           // handle of window
      UINT wMsgFilterMin,  // first message
      UINT wMsgFilterMax   // last message
    );
    hWnd 
    Handle to the window whose messages are to be retrieved. One value has a special meaning: Value Meaning 
    NULL GetMessage retrieves messages for any window that belongs to the calling thread and thread messages posted to the calling thread via PostThreadMessage. 
      

  14.   

    MSDN2005的地址:
    ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.WIN32COM.v10.en/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesfunctions/getmessage.htm在Return Value和Res 中间有个Warning ,那段代码就是从Show Example 抄来的.在没看到那个Warning 前我一直当
    while (GetMessage(&msg, NULL, 0, 0)) 
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    是标准写法,但现在觉得这么写会不会有健壮性的隐患.
      

  15.   

    BOOL bRet;while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)

        if (bRet == -1)
        {
            // handle the error and possibly exit(这里可以做处理,比如exit(0),提高健壮性)
        }
        else
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
    }
    http://www.bc-cn.net/bbs/dispbbs.asp?boardID=55&ID=36185有人提过
      

  16.   

    while( GetMessage( &msg, cwnd.m_hWnd, 0, 0 ))

     if (msg == WM_QUIT) 
       break;
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
    }
      

  17.   

    // handle the error and possibly exit(这里可以做处理,比如exit(0),提高健壮性)我觉得若是在此处能显示出错原因会不会更好些?还有一点想不明白,消息队列中的消息应该是取不完的,即使你不做任何操作也会有默认的消息产生,对么?而且GetMessage()接到WM_QUIT时返回 0  ,循环应该就终止了
      

  18.   

    To:  muroachanf(阿远之秋去) 你的写法有问题,应改为 if (msg.message == WM_QUIT)但结束程序后进程中还存在
      

  19.   

    是啊,GetMessage()接到WM_QUIT时返回 0,循环终止,但是你刚开始用的cwnd.m_hWnd 做参数,而非NULL, 当你WM_CLOSE时候,你把句柄摧了,再次以cwnd.m_hWnd 做参数GetMessage()肯定返回-1了,是永远也收不到WM_QUIT消息,参数改为NULL,
    GetMessage retrieves messages for any window that belongs to the calling thread and thread messages posted to the calling thread via PostThreadMessage.
    能接受包括主窗口句柄在类所有的消息,当然也有WM_QUIT.至于显示出错原因,没必要了,这样的调用很少出错,MSDN上也说了
    To get extended error information, call GetLastError.
      

  20.   

    是啊,GetMessage()接到WM_QUIT时返回 0,循环终止,但是你刚开始用的cwnd.m_hWnd 做参数,……-------------------------------循环终止了,而GetMessage()是在循环中的,也就不可能再调用到。虽然句柄无效,但也不会再用来当参数了。
      

  21.   

    而且句柄无效和句柄为NULL 是一个概念吗?在C++中,释放一个指针,只是释放那块内存,指针指向的地址是不变的,也就是不会为 NULL,不知VC 中是不是也这样
      

  22.   

    循环终止了,而GetMessage()是在循环中的,也就不可能再调用到。虽然句柄无效,但也不会再用来当参数了。
    ------------------------------------------------------------------------------------
    关键是循环没有终止,因为 GetMessage( &msg, cwnd.m_hWnd, 0, 0 ))  收不到WM_QUIT消息,
     GetMessage( &msg,NULL, 0, 0 )); //这里的NULL如果传入了NULL句柄, 则表示
    GetMessage retrieves messages for any window that belongs to the calling thread and thread messages posted to the calling thread via PostThreadMessage.句柄无效和句柄为NULL 不是一个概念
    DestroyWindow(hwnd)之后,句柄无效,但句柄!=NULL,这有点象指针一样,释放指针,但指针!=NULL,其实说白了,句柄也是一种指针.. (VC是开发环境当然和C++中一样了)
      

  23.   

    上面的问题已由seu07201213 解决了,过会儿再结,贴再加20分,求下面的解
    我把 WM_PAINT 消息处理做了些改动,通不过了,为什么? case WM_PAINT:
    //PAINTSTRUCT  ps;
    HDC hdc;
    //hdc=BeginPaint(hwnd,&ps);
    CPaintDC hdc=::GetDC(hwnd);

    TextOut(hdc,0,50,TEXT("VC2005.net"), (int)strlen("VC2005.net"));
    //EndPaint(hwnd,&ps);
            break;
      

  24.   

    我用的是全局的,SDK 也有吧,MSDN 上都看的到
      

  25.   

    你既然模拟 MFC 的 CWnd 类的封装,也不能再引入#include <AFXWIN.H>了中的MFC类了
    否则会引起冲突.......要么学它的CPaintDC也来个封装
      

  26.   

    CPaintDC
    The CPaintDC class is a device-context class derived from CDC. Header file: Afxwin.h 
      

  27.   

    MFC 的类是不是像我那样,把API 的函数封装进来?
      

  28.   

    为什么在MFC中可以用API函数,反之不行?
      

  29.   

    MFC是对API的封装,反之也可以用
    #include <AFXWIN.H>
    工程设置成Use MFC in a Shared dll就行了但你的不行,你定义了CWnd和MFC中的CWnd冲突
      

  30.   

    工程设置成Use MFC in a Shared dll就行了在哪设置的?我用的是vc2005
      

  31.   

    为什么把WM_PAINT 消息处理做如下改动后,结果什么都不响应了? case WM_PAINT:
    //PAINTSTRUCT  ps;
    HDC hdc;
    hdc=::GetDC(hwnd);
    //hdc=BeginPaint(hwnd,&ps);
    //CPaintDC hdc=::GetDC(hwnd);

    TextOut(hdc,0,50,TEXT("VC2005.net"), (int)strlen("VC2005.net"));
    //EndPaint(hwnd,&ps);
            break;