2011-05-08 61 views
0

我得到了以下兩個CDialog類,它們是用於從模板和從CDialog中取消的類CMainDialog創建對話框窗口,並且有一些方法可以操作對話框上的控件。不知何故,類的成員更改

class CDialog 
    { 
    public: 
     CDialog(DWORD dwTemplate) : m_dwTemplateID(dwTemplate), m_hWnd(NULL) {}; 
     virtual ~CDialog() {}; 

     static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 

     virtual BOOL Create(HINSTANCE hInstance, HWND hParent = NULL); 

     BOOL Show(BOOL bShow); 
    private: 
     DWORD m_dwTemplateID; 

    protected: 
     HWND m_hWnd; 
     virtual INT_PTR HandleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 
    }; 

//基地對話框實現

#include "BaseDialog.h" 

//statics 

INT_PTR CALLBACK Inc::CDialog::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    Inc::CDialog* pDialog = nullptr; 

    if(uMsg == WM_INITDIALOG) 
    { 
     //save address of the CDialog-object into the dialog´s userdata 
     pDialog = (Inc::CDialog*)lParam; 
     SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pDialog); 
    } 
    else 
    { 
     //get the pointer 
     pDialog = (Inc::CDialog*)GetWindowLongPtr(hWnd, GWLP_USERDATA); 
    } 

    if(pDialog) 
    { 
     //handle messages 
     return pDialog->HandleMessages(hWnd, uMsg, wParam, lParam); 
    } 

    return FALSE;  //!pDialog 
} 

INT_PTR Inc::CDialog::HandleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch(uMsg) 
    { 
    case WM_CLOSE: 
      DestroyWindow(m_hWnd); 
     return TRUE; 
    case WM_DESTROY: 
      PostQuitMessage(0); 
      return TRUE; 
    }; 

    return FALSE;  //Message not handled => system will take action 
} 

BOOL Inc::CDialog::Create(HINSTANCE hInstance, HWND hParent) 
{ 
    m_hWnd = CreateDialogParam(hInstance, MAKEINTRESOURCE(m_dwTemplateID), hParent, DialogProc, (LPARAM)this); 
    if(m_hWnd == NULL) 
     return FALSE; 

    return TRUE; 
} 

//return values: TRUE => window was previously visible, FALSE otherwise 
BOOL Inc::CDialog::Show(BOOL bShow) 
{ 
    if(bShow) 
     return ShowWindow(m_hWnd, SW_SHOWNORMAL); 
    return ShowWindow(m_hWnd, SW_HIDE); 
} 

// CMainDialog

class CMainDialog : 
     public Inc::CDialog 
    { 
    public: 
     CMainDialog(DWORD dwTemplateID); 
     virtual ~CMainDialog(void); 

     virtual INT_PTR HandleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 

    private: 
     static const char m_szDates[8][14]; 

     //Dialog control item 
     HWND m_hDateComboBox; 
     HWND m_hItemListBox; 
     HWND m_hDescriptionEditBox; 
     HWND m_hButtonClose; 
     HWND m_hButtonSave; 
     HWND m_hButtonDelete; 

     //get save the control item handles 
    public: 
     void GetControlHandles(); 
    public: 
     void PopulateDateComboBox(); 
    }; 

// CMAIN對話實現

#include "MainDialog.h" 
#include <WindowsX.h> 
#include "resource.h" 
#include <stdexcept> 

//statics 
const char Inc::CMainDialog::m_szDates[8][14] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Single Event"}; 

Inc::CMainDialog::CMainDialog(DWORD dwTemplateID) : CDialog(dwTemplateID) 
{ 
} 


Inc::CMainDialog::~CMainDialog(void) 
{ 
} 

//adds the entries in m_szDates to the Combo Box for choosing the date 
void Inc::CMainDialog::PopulateDateComboBox() 
{ 
    for(unsigned short s = 0; s < 8; s++) 
    { 
     if(ComboBox_AddString(m_hDateComboBox, m_szDates[s]) <= CB_ERR) 
      throw(std::runtime_error("ComboBox_AddString() failed")); 
    } 
} 

INT_PTR Inc::CMainDialog::HandleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch(uMsg) 
    { 
    case WM_INITDIALOG: 
      this->GetControlHandles(); // It happens here !!!!!!! <==== 
      this->PopulateDateComboBox(); 
     return TRUE; 
    } 

    return Inc::CDialog::HandleMessages(hWnd, uMsg, wParam, lParam);  //if message isnt handled here, default handling 
} 

void Inc::CMainDialog::GetControlHandles() 
{ 
    //Get Control window handles 
    m_hDateComboBox = GetDlgItem(m_hWnd, IDC_COMBO_DAY); 
    m_hItemListBox = GetDlgItem(m_hWnd, IDC_LIST); 
    m_hDescriptionEditBox = GetDlgItem(m_hWnd, IDC_EDIT_DESCRIPTION); 
    m_hButtonClose = GetDlgItem(m_hWnd, IDC_BUTTON_CLOSE); 
    m_hButtonSave = GetDlgItem(m_hWnd, IDC_BUTTON_SAVE_CHANGE); 
    m_hButtonDelete = GetDlgItem(m_hWnd, IDC_BUTTON_DELETE_ITEM); 
} 

的問題,我確實遇到是,在個CMainDialog :: HandleMessages()當WM_INITDIALOG應該處理的m_hWnd成員成員函數NULL甚至壽CDialog的:創建()功能確實成功和窗口句柄返回m_hWnd。

的CDialog的:DialogProc-過程似乎是在去上班的路上,它得到從WM_INITDIALOG的LPARAM正確的地址,讓pDialog終場指向正確的對象和呼叫it's成員函數。

也許你看到我錯過了什麼或者我做錯了什麼。

預先感謝您調用CreateDialog期間處理

回答

1

你的WM_INITDIALOG消息,而分配給m_hWnd(CreateDialog的結果)CreateDialog結束後完成。

解決方案:將hWnd傳遞給Base類的WM_INITDIALOG中的GetControlHandle(HWND hWnd)或設置m_hWnd。

1

這種情況的解決方法是在搬運的WM_INITDIALOG添加pDialog->m_hWnd = hWnd;

if(uMsg == WM_INITDIALOG) 
{ 
    //save address of the CDialog-object into the dialog´s userdata 
    pDialog = (Inc::CDialog*)lParam; 
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pDialog); 
    pDialog->m_hWnd = hWnd; 
} 

這確保m_hWnd任何調用之前被設置爲HandleMessage