2013-02-05 9 views
0

我設法在此控件中繪製矩形,但存在兩個問題。首先是用鼠標移動選擇文件夾對話框後顯示的白色矩形。我知道這裏的問題是要連接正確的信息。我已經選擇了WM_ERASEBKGND,它在創建對話框窗口時觸發,但不起作用,必須在未顯示的部分控件返回到屏幕上時調用WM_ERASEBKGND,所以我必須將窗口拖動到邊緣,以便部分控件不可見並將其拖回,然後顯示白色矩形。但是第二個問題出現了。它還涵蓋了控件的文本。在沒有WM_CTLCOLORSTATIC的對話窗口不會收到的select-for-folder對話框中着色靜態控件

所以這裏是我的嘗試,任何想法?

#include <windows.h> 
#include <shlobj.h> 

WNDPROC origStaticProc; 
LRESULT CALLBACK myStaticProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (uMsg) { 
    case WM_ERASEBKGND: { 
     HDC dc = GetDC(hWnd); 
     RECT clientRect; 
     GetClientRect(hWnd,&clientRect); 
     FillRect(dc, &clientRect, (HBRUSH)GetStockObject(WHITE_BRUSH)); 
     ReleaseDC(hWnd, dc); 
     break; 
    } 
    } 
    return CallWindowProc(origStaticProc, hWnd, uMsg, wParam, lParam); 
} 

int CALLBACK BrowseCallBackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { 
    switch(uMsg) { 
    case BFFM_INITIALIZED: { 
     HWND static_control = NULL; 
     char szClassName[_MAX_PATH]; 
     for (HWND hChild = GetWindow(hwnd, GW_CHILD); hChild != NULL; hChild = GetNextWindow(hChild, GW_HWNDNEXT)) 
     { 
     if ((GetWindowLong(hChild, GWL_STYLE) & WS_VISIBLE) == 0) continue; 
     GetClassName(hChild, szClassName, _countof(szClassName)); 
     if (!strcmp("Static",szClassName)) { 
      static_control = hChild; 
      break; 
     } 
     } 
     HFONT hFont = CreateFont (13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Fixedsys")); 
     SendMessage(static_control, WM_SETFONT, (WPARAM)hFont, TRUE); 
     origStaticProc = (WNDPROC) SetWindowLongW(static_control, GWL_WNDPROC,(LONG) myStaticProc); 
     break; 
    } 
    } 
} 

int main() { 
    using namespace std; 
    BROWSEINFOW bi; 
    LPITEMIDLIST pidl; 
    LPMALLOC pMalloc; 
    if (SUCCEEDED (::SHGetMalloc (&pMalloc))) { 
    ::ZeroMemory (&bi,sizeof(bi)); 
    bi.hwndOwner = NULL; 
    bi.lpszTitle = L"I should be visible on a white background. Now you must drag me to edge of the screen and back."; 
    bi.pszDisplayName = 0; 
    bi.pidlRoot = 0; 
    bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_VALIDATE | BIF_USENEWUI | BIF_UAHINT; 
    bi.lpfn = BrowseCallBackProc; 
    bi.lParam = (LPARAM)L"d:\\"; 
    pidl = ::SHBrowseForFolderW(&bi); 
    } 
} 

如何,它看起來像:

how it looks like

如何,當然應該是:

how it of course should be

+0

請問爲什麼你試圖這樣做呢?用這種Windows界面搞糟不是個好主意。當我們處理它時,*正確的*方法是使用'WM_CTLCOLOR'和'WM_CTLCOLORSTATIC'。爲什麼你不想這樣做? –

+0

@NikBougalis:怎麼樣?通過向控制hwnd發送或發佈消息(或者我應該以某種方式收到此消息,在瀏覽文件夾窗口wndproc中或在靜態wndproc中?)? WM_CTLCOLORSTATIC的Wparam是一種叫做「設備上下文」的東西,該如何獲取?而WM_CTLCOLOR僅適用於16b。 – rsk82

+0

你不明白WM_CTLCOLORSTATIC如何工作。 *子*(即靜態)將消息發送到其父*(即對話框),並且它在WPARAM中提供設備上下文以供其父母使用。 –

回答

0

明白了。問題是我不知道用於SHBrowseForFolder的回調函數不同於窗口本身的回調函數。它出來了,我必須做另一個功能來繼承對話框。

這是醜陋的和不安全的代碼,但它編譯和說明了原理。

#include <windows.h> 
#include <shlobj.h> 

WNDPROC origBffProc; 
LRESULT CALLBACK bffProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    static HBRUSH hBrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH); 
    switch (uMsg) { 
    case WM_CTLCOLORSTATIC: { 
     HDC hdcStatic = (HDC) wParam; 
     SetTextColor(hdcStatic, RGB(255,0,0)); 
     SetBkColor(hdcStatic, RGB(255,255,0)); 
     return (INT_PTR)hBrush; 
    } 
    } 
    return CallWindowProc(origBffProc, hWnd, uMsg, wParam, lParam); 
} 

int CALLBACK BrowseCallBackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { 
    switch(uMsg) { 
    case BFFM_INITIALIZED: { 
     HWND static_control = NULL; 
     char szClassName[_MAX_PATH]; 
     for (HWND hChild = GetWindow(hwnd, GW_CHILD); hChild != NULL; hChild = GetNextWindow(hChild, GW_HWNDNEXT)) 
     { 
     if ((GetWindowLong(hChild, GWL_STYLE) & WS_VISIBLE) == 0) continue; 
     GetClassName(hChild, szClassName, _countof(szClassName)); 
     if (!strcmp("Static",szClassName)) { 
      static_control = hChild; 
      break; 
     } 
     } 
     HFONT hFont = CreateFont (13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Fixedsys")); 
     PostMessage(static_control, WM_SETFONT, (WPARAM)hFont, TRUE); 
     origBffProc = (WNDPROC) SetWindowLongW(hwnd, GWL_WNDPROC,(LONG) bffProc); 
     break; 
    } 
    } 
} 
int main() { 
    using namespace std; 
    BROWSEINFOW bi; 
    LPITEMIDLIST pidl; 
    LPMALLOC pMalloc; 
    if (SUCCEEDED (::SHGetMalloc (&pMalloc))) { 
    ::ZeroMemory (&bi,sizeof(bi)); 
    bi.hwndOwner = NULL; 
    bi.lpszTitle = L"You are about to erase a directory, be careful! (and don't blame me)"; 
    bi.pszDisplayName = 0; 
    bi.pidlRoot = 0; 
    bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_VALIDATE | BIF_USENEWUI | BIF_UAHINT; 
    bi.lpfn = BrowseCallBackProc; 
    bi.lParam = (LPARAM)L"d:\\"; 
    pidl = ::SHBrowseForFolderW(&bi); 
    } 
}