2015-07-19 69 views
0

我正在嘗試圍繞WINAPI工作,以實現作爲自定義類的成員的無模式對話框窗口的過程。我不確定這是可能的,但我希望有人知道一種方式。目標是讓程序訪問自定義類的成員變量綁定對話框過程作爲自定義類的方法

我知道使用普通窗口是可能的。

//MyClass.h 
class MyClass 
{ 
    public: 
    bool init(...) 
    static LRESULT CALLBACK redirect(HWND hWnd, UINT msg, 
              LPARAM lParam, WPARAM wParam); 
    LRESULT myWndProc(HWND hWnd, UINT msg, 
         LPARAM lParam, WPARAM wParam); 

    private: 
    HWND m_MainHwnd; 
} 

通過定義指針重定向到非靜態實際程序處理的靜態成員函數,該過程可以是一個成員函數:

//MyClass.cpp 
MyClass::init(...) 
{ 
    //Create the window class for the main Window// 
    m_windowed = windowed; 
    WNDCLASSEX wc; //Create a new extended windows class 

    wc.cbSize = sizeof(WNDCLASSEX); //Size of our windows class 
    wc.style = CS_HREDRAW | CS_VREDRAW; //class styles 
    wc.lpfnWndProc = MyClass::redirect; //Default windows procedure function 
    wc.cbClsExtra = NULL; //Extra bytes after our wc structure 
    wc.cbWndExtra = NULL; //Extra bytes after our windows instance 
    wc.hInstance = hInstance; //Instance to current application 
    wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); //Title bar Icon 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); //Default mouse Icon 
    wc.hbrBackground = CreateSolidBrush(0xFFFFFF); //Window bg color 
    wc.lpszMenuName = NULL; //Name of the menu attached to our window 
    wc.lpszClassName = m_windowName; //Name of our windows class 
    wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); //Icon in your taskbar 

    if (!RegisterClassEx(&wc)) //Register our windows class 
    { 
     //if registration failed, display error 
     MessageBox(NULL, "Error registering Main Window class", 
      "Error", MB_OK | MB_ICONERROR); 
     return false; 
    } 

    m_MainHwnd = CreateWindowEx( //Create our Extended Window 
     NULL, //Extended style 
     m_windowName, //Name of our windows class 
     m_windowName, //Name in the title bar of our window 
     WS_OVERLAPPEDWINDOW | WS_VISIBLE, //style of our window | Make it    visible on showWindow cmd 
     30, 30, //Top left corner of window 
     width, //Width of our window 
     height, //Height of our window 
     NULL, //Handle to parent window 
     NULL, //Handle to a Menu 
     hInstance, //Specifies instance of current program 
     this //used for an MDI client window 
    ); 
} 

見線在設置在WNDCLASSEX中:wc.lpfnWndProc = MyClass :: redirect;?這是有效的,因爲下面的實現重定向靜態函數的:

MyClass::redirect(HWND hwnd, UINT msg, LPARAM lParam, WPARAM wParam) 
{ 
    if (msg == WM_CREATE) SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)((CREATESTRUCT FAR *)lParam)->lpCreateParams); 
    MyClass * pObject = (MyClass*)((LONG_PTR)GetWindowLongPtr(hwnd, GWL_USERDATA)); 
    if (pObject) return pObject->MyWndProc(hwnd, msg, wParam, lParam); 

    //return the message for windows to handle it 
    return DefWindowProc(hwnd, 
     msg, 
     wParam, 
     lParam); 
}; 

這可讓您實現MyWndProc(...)完全像任何其他成員的方法。

Now!我真的希望能夠對我的無模式對話框做同樣的事情 - 因爲知道「MyClass」的成員變量是相當重要的。另外 - 我喜歡我可以設計它並按照我喜歡的方式重新設計它(如果我必須使用普通窗口 - 將代碼全部設計成單調乏味)。

是否有可能?

預先感謝您!

回答

1

是的,可以通過對話框或多或少地使用此方法。

而不是使用WM_CREATE來存儲this指針,您使用WM_INITDIALOG。請注意,用戶數據本身傳遞到WM_INITDIALOG,lParam本身 - 沒有像WM_CREATE那樣的解除引用的結構。

您可以將指針存儲在DWLP_USER中,該對話框的所有者可以使用指針大小的窗口數據槽。

如果數據指針尚未分配,最後的區別僅僅是返回FALSE - 您不會從對話框過程調用DefWindowProc

class MyClass 
{ 
public: 
     static INT_PTR CALLBACK dlgRedirect(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 
     LRESULT myDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 
} 

//... 
HWND hwndDlg = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_MYDIALOG), hwndParent, 
    MyClass::dlgRedirect, reinterpret_cast<LPARAM>(this)); 

//... 
INT_PTR CALLBACK MyClass::dlgRedirect(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    if (uMsg == WM_INITDIALOG) SetWindowLongPtr(hWnd, DWLP_USER, lParam); 
    MyClass* pThis = reinterpret_class<MyClass*>(GetWindowLongPtr(hWnd, DWLP_USER)); 
    if (pThis) return pThis->myDlgProc(hWnd, uMsg, wParam, lParam); 
    return FALSE; 
} 

INT_PTR MyClass::myDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    // real dialog procedure here 
} 
+0

謝謝你太多了..這正是我一直在尋找的mod!我可以問問你是否已經知道這一點,或者你是否有源?只是出於好奇。 – Silverback

+0

你不知道我有多開心!我幾乎放棄了!謝謝! – Silverback

+0

@Silverback我認爲這是一個衆所周知的技術,我一直在使用它多年。不記得我第一次拿起它的地方。 –