Здравствуйте все! Снова я, снова с ламерским вопросом. Пытаюсь изменить цвет окна и всех контролов со стандартного серого на что-нибудь приятное зелененькое. Цвет главного окна изменил, поместив в соответствующее поле нужное значение. Код (Text): RGB 114,255,128 PUSH EAX CALL CreateSolidBrush mov wc.hbrBackground, EAX При этом цвет окна изменился, а кнопки, надписи, меню остались серенькими. В принципе логично,- подумал я. Ведь свойства окна и кнопок задаются в разных местах? Ладно, пробую изменить цвет кнопок с помощью функции SetBkColor. В структуру сообщения WM_PAINT (после вызова BeginPaint) включаю: Код (Text): invoke SetBkColor, Button1, 3 ; где Button1 хендл кнопки И... никаких изменений Пробовал вызывать SetBkColor, непосредственно после создания кнопки: Код (Text): invoke CreateWindowEx, WS_EX_LEFT, ADDR szBtnClass, ADDR szBtn1Text, WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT, Button1L, Button1T, Button1W, Button1H, hWnd, NULL, hInst, NULL mov Button1, eax invoke SetBkColor, Button1, 255 Тот же результат. В смысле отсутствие результата. Пробовал изменять фон кнопки с помощью посылки сообщения: INVOKE SendMessage, Button1, TVM_SETBKCOLOR, 0, 00000000h И, блин, опять ничего... Подскажите пожалуйста, где я опять косячу?
WM_CTLCOLORBTN WM_CTLCOLOREDIT WM_CTLCOLORDLG WM_CTLCOLORLISTBOX WM_CTLCOLORSCROLLBAR WM_CTLCOLORSTATIC ищи описание.
Вроде почитал на MSDN, но мало что прояснилось. Так. Сообщение WM_CTLCOLORBTN посылается родительскому окну кнопки для того, чтобы изменять фон и содержимое кнопки. Посылать сообщение необходимо перед тем как нарисовать кнопку. Посылка собщения должна выглядеть таким образом (как я понял): invoke SendMessage, hWnd, WM_CTLCOLORBTN, 45, Button1 Непонятно, если кнопка еще не нарисована, то как мы узнаем ее хендл? Попробовал, конечно, поставить перед CreateWindowEx (для кнопки). Ничего не получилось. Если под рисованием имеется ввиду ShowWindow, то я на всякий случай пробовал посылать сообщение и перед ее вызовом. Результата нет. Если я правильно понял,то в wParam сообщения помещается указатель на будущее содержимое кнопки "Handle to the display context for the button". А что это должно быть если мне надо только поменять цвет? Если кто-нибудь знает ссылку на такой пример, дайте пожалуйста.
Ты направильно понял. WM_CTLCOLORBTN - это нотификация, и отсылается родительскому(по отношению к кнопке) окну. При обработке, WndProc должна вернуть хенд кисти. Ксить создавай через CreateSolidBrush.
То есть все должно выглядеть вот так? .ELSEIF uMsg == WM_CTLCOLORBTN mov eax, lParam .if eax == Button1 RGB 122,122,1 INVOKE CreateSolidBrush, EAX INVOKE SetBkColor,Button1,EAX .endif Опять ничего не вышло
Код (Text): ... .data hbrBtnBrush dd 0 ... ; При инициализации RGB 122,122,1 push eax call CreateSolidBrush mov hbrBtnBrush, eax ... ; Функция окна ... .ELSEIF uMsg == WM_CTLCOLORBTN mov eax, lParam .if eax == Button1 ; Устанавливаем прозрачный фон для текста кнопки push TRANSPARENT push wParam call SetBkMode ; Устанавливаем цвет текста кнопки RGB 0,0,128 push eax push wParam call SetTextColor ; Возвращаемым значением функции окна должен быть хендл кисти mov eax, hbrBtnBrush ; От этой инструкции до выхода из функции eax не должен изменится .endif ...
Огромное спасибо, rmn!!! Как все-таки сложно все это усваивать. Вроде и читаю много, и в разных исходниках ковыряюсь, и в отладчике гоняю все что можно, А все равно очень туго идет Спасибо еще раз!
Попробовал похожим образом: Код (Text): .IF uMsg==WM_CREATE ... RGB 122,122,1 invoke CreateSolidBrush, eax mov hbrBtnBrush, eax ... .ELSEIF uMsg == WM_CTLCOLORBTN mov eax, lParam .IF eax==hbExit invoke SetBkMode, wParam, TRANSPARENT RGB 0,0,128 invoke SetTextColor, wParam, eax mov eax, hbrBtnBrush ret .ENDIF У меня не заработало. Кнопка как была стандартного цвета с чёрным шрифтом, так и осталась. Какие ещё тут нюансы могут быть?
У меня, кстати, тоже почемуто не получилось. Все хотел отписаться, но, то времени не было, то я все пытался сам чего-то поправить. Ньюансы кое-какие есть. Из MSDN: Buttons with the BS_PUSHBUTTON, BS_DEFPUSHBUTTON, or BS_PUSHLIKE styles do not use the returned brush. Buttons with these styles are always drawn with the default system colors. Пробовал без этих стилей, но все равно не получается.
Поковырялся с XXControls и еще с парой исходников. Оказалось для диалоговых окошек. И вообще довольно перегружено информацией. Очень тяжело воспринимается. Ничего не понял
Простите, что поднимаю старую тему, но вопрос еще остаетя актуальным для меня. За это время прочесал множество ресурсов (как русских, так и иностранных) и сложилась интересная ситуация. На всех форумах, где я задавал этот вопрос, развитие событий было примерно одинаковым. Либо давали пример кода, аналогичного тому, что привел rmn; либо отсылали к MSDN; либо давали ссылку на какой-нибудь левый исходник мало связаный с вопросом. Я честно пытался все это применять, но результата так и не добился. После этого я обычно признавался в собственной чайниковости стыдливо просил помочь исправить мой исходник. После этого все куда-то отваливали. На англоязычных форумах куча тем с вопросом "How use WM_CTLCOLORBTN", но все они по содержанию аналогичны текущему топику. Проблему я смог решить несколькими путями. Использовать в качестве кнопок картинки, сабклассинг или рисование кнопок вручную. Но это какие-то кривые обходные пути. А вопрос так и остался. Как с помощью обработки WM_CTLCOLORBTN изменить цвет кнопки? Что интересно со "статиком" и "эдитом" все получается, а кнопки как заколдованные. Если кто-нибудь делал такие вещи, не посчитайте за труд, выложите, пожалуйста, простенький рабочий исходник.
MSDN: The WM_CTLCOLORBTN message is sent to the parent window of a button before drawing the button. The parent window can change the button's text and background colors. However, only owner-drawn buttons respond to the parent window processing this message.
Sturgeon Только так. ЗЫ: Во всяком случае я именно так обычно делаю (3й вариант или через owner-drawn) и никаких неудобств не испытываю. ЗЫЫ: Вот пример нашёл у себя на C (это не owner-drawn, а самодельный контрол, прикидывающийся кнопкой): Код (Text): long __stdcall ButtonProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){ char button_buf[32]; HDC hDC; PAINTSTRUCT paint; HPEN hOldPen; HBRUSH hOldBrush; HFONT hOldFont; RECT rc; POINT pt; int h, i, j; switch(uMsg){ case WM_ERASEBKGND: return 1; case WM_PAINT: hDC = BeginPaint(hWnd,&paint); if(paint.rcPaint.bottom != paint.rcPaint.top){ GetClientRect(hWnd,&rc); GetWindowText(hWnd,button_buf,sizeof(button_buf) - 1); i = IsWindowEnabled(hWnd); j = GetWindowLong(hWnd,GWL_USERDATA); h = j & 2; j &= 1; SetBkMode(hDC,TRANSPARENT); hOldFont = SelectObject(hDC,hStaticFnt); hOldPen = SelectObject(hDC,CreatePen(PS_SOLID,0,h ? 0xFFFFFF : (j ? 0x6A240A : 0x808080))); SetTextColor(hDC,h ? 0xFFFFFF : (i ? 0 : 0x808080)); hOldBrush = SelectObject(hDC,CreateSolidBrush(h ? 0x800000 : (j ? 0xE2D2CB : 0xCFD6DA))); Rectangle(hDC,0,0,rc.right,rc.bottom); DrawTextEx(hDC,button_buf,-1,&rc,DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE,0); DeleteObject(SelectObject(hDC,hOldPen)); DeleteObject(SelectObject(hDC,hOldBrush)); SelectObject(hDC,hOldFont); } EndPaint(hWnd,&paint); break; case WM_LBUTTONDOWN: SetWindowLong(hWnd,GWL_USERDATA,2); InvalidateRect(hWnd,0,0); break; case WM_LBUTTONUP: SetWindowLong(hWnd,GWL_USERDATA,1); InvalidateRect(hWnd,0,0); PostMessage(GetParent(hWnd),WM_COMMAND,GetWindowLong(hWnd,GWL_ID),0); break; case WM_MOUSEMOVE: pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); GetClientRect(hWnd,&rc); if(!PtInRect(&rc,pt)){ ReleaseCapture(); SetWindowLong(hWnd,GWL_USERDATA,0); }else{ if(GetCapture() != hWnd){ SetCapture(hWnd); SetWindowLong(hWnd,GWL_USERDATA,1); }else break; } case WM_ENABLE: InvalidateRect(hWnd,0,0); break; default: return DefWindowProc(hWnd,uMsg,wParam,lParam); } return 0; } Регистрируется обычным способом... Далее можно использовать хоть в шаблоне диалога вместо обычных кнопок, хоть по CreateWindow.
Quantum То есть WM_CTLCOLORBTN использовать нельзя? А для чего он тогда вообще нужен? rmn n0name Есть у меня MSDN. И с BS_OWNERDRAW я тоже пробовал. Можете написать рабочий код?
Jupiter Это для диалогового окна, а хотелось для обычного. И еще я пробовал перетранслировать его со своими настройками RGB, но постоянно требовались дллки, библиотеки, инклуды. В итоге я запутался и ничего у меня не получилось. З.Ы. Это не потому, что исходник непонятный, а потому, что я пока чайник.