раскрасить статический элемент управления в диалоге выбора папки без WM_CTLCOLORSTATIC, который не получает это диалоговое окно

Мне удалось нарисовать прямоугольник в этом элементе управления, но есть две проблемы. Во-первых, белый прямоугольник отображается после перемещения мышью по диалоговому окну выбора папки. Я знаю, что проблема здесь в том, чтобы подключить правильное сообщение. Я выбрал WM_ERASEBKGND, который запускается при создании диалогового окна, но затем он не имеет никакого эффекта, он должен вызываться, когда часть элемента управления, не показанная ранее, возвращается на экран, поэтому я должен перетащить окно к краю, чтобы часть элемент управления не виден и перетащите его назад, тогда будет показан белый прямоугольник. Но возникает вторая проблема. Он также охватывает текст элемента управления.

Так вот моя попытка, есть идеи?

#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);
}
}

как это выглядит:

как это выглядит

как это конечно должно быть:

как это должно быть

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);
}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector