나는 이미 사용자 지정 그리기, 소유자 그리기 및 서브 클래 싱에 대해 알고 있습니다. 지금까지 내 선택은 맞춤 그림입니다. 서브 클래 싱이 나의 두 번째 선택이지만 버튼의 양은 엄청납니다. 누구든지 다른 의견이 있으면 의견을 말하십시오. 어쨌든 나는 사용자 정의 도면을위한 코드를 게시 할 것입니다. Win32에서는 어디서나 직접적인 대답이 없기 때문입니다.버튼의 기능을 win32에서 유지하면서 버튼의 색상을 변경하는 방법은 무엇입니까?
1
A
답변
5
가
제 버튼이 선택되고, 가압하고, 두번째 버튼을 가압 할 때 마지막 쇼와 마우스가 넘으면 것도, 두 번째 프로그램을 선택하지 않은 경우첫번째 픽처 도시 합니다 (알 밝기 증가 - cutom hilight). 이렇게하려면 NM_CUSTOMDRAW 메시지를 잡고 직접 페인트해야합니다. 그리고 이것이 당신이하는 방법입니다. 또한 그라디언트 브러시 기능과 몇 가지 설명이 추가되었습니다.
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include <Windows.h>
#include <Commctrl.h>
#define IDC_EXIT_BUTTON 101
#define IDC_PUSHLIKE_BUTTON 102
HBRUSH CreateGradientBrush(COLORREF top, COLORREF bottom, LPNMCUSTOMDRAW item)
{
HBRUSH Brush = NULL;
HDC hdcmem = CreateCompatibleDC(item->hdc);
HBITMAP hbitmap = CreateCompatibleBitmap(item->hdc, item->rc.right-item->rc.left, item->rc.bottom-item->rc.top);
SelectObject(hdcmem, hbitmap);
int r1 = GetRValue(top), r2 = GetRValue(bottom), g1 = GetGValue(top), g2 = GetGValue(bottom), b1 = GetBValue(top), b2 = GetBValue(bottom);
for(int i = 0; i < item->rc.bottom-item->rc.top; i++)
{
RECT temp;
int r,g,b;
r = int(r1 + double(i * (r2-r1)/item->rc.bottom-item->rc.top));
g = int(g1 + double(i * (g2-g1)/item->rc.bottom-item->rc.top));
b = int(b1 + double(i * (b2-b1)/item->rc.bottom-item->rc.top));
Brush = CreateSolidBrush(RGB(r, g, b));
temp.left = 0;
temp.top = i;
temp.right = item->rc.right-item->rc.left;
temp.bottom = i + 1;
FillRect(hdcmem, &temp, Brush);
DeleteObject(Brush);
}
HBRUSH pattern = CreatePatternBrush(hbitmap);
DeleteDC(hdcmem);
DeleteObject(Brush);
DeleteObject(hbitmap);
return pattern;
}
LRESULT CALLBACK MainWindow(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HBRUSH defaultbrush = NULL;
static HBRUSH hotbrush = NULL;
static HBRUSH selectbrush = NULL;
static HBRUSH push_uncheckedbrush = NULL;
static HBRUSH push_checkedbrush = NULL;
static HBRUSH push_hotbrush1 = NULL;
static HBRUSH push_hotbrush2 = NULL;
switch (msg)
{
case WM_CREATE:
{
HWND Exit_Button = CreateWindowEx(NULL, L"BUTTON", L"EXIT",
WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
50, 50, 100, 100, hwnd, (HMENU)IDC_EXIT_BUTTON, NULL, NULL);
if(Exit_Button == NULL)
{
MessageBox(NULL, L"Button Creation Failed!", L"Error!", MB_ICONEXCLAMATION);
exit(EXIT_FAILURE);
}
HWND Pushlike_Button = CreateWindowEx(NULL, L"BUTTON", L"PUSH ME!",
WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | BS_PUSHLIKE,
200, 50, 100, 100, hwnd, (HMENU)IDC_PUSHLIKE_BUTTON, NULL, NULL);
if(Pushlike_Button == NULL)
{
MessageBox(NULL, L"Button Creation Failed!", L"Error!", MB_ICONEXCLAMATION);
exit(EXIT_FAILURE);
}
}
break;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_EXIT_BUTTON:
{
SendMessage(hwnd, WM_CLOSE, 0, 0);
}
break;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR some_item = (LPNMHDR)lParam;
if (some_item->idFrom == IDC_EXIT_BUTTON && some_item->code == NM_CUSTOMDRAW)
{
LPNMCUSTOMDRAW item = (LPNMCUSTOMDRAW)some_item;
if (item->uItemState & CDIS_SELECTED)
{
//Select our color when the button is selected
if (selectbrush == NULL)
selectbrush = CreateGradientBrush(RGB(180, 0, 0), RGB(255, 180, 0), item);
//Create pen for button border
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
//Select our brush into hDC
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, selectbrush);
//If you want rounded button, then use this, otherwise use FillRect().
RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5);
//Clean up
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
//Now, I don't want to do anything else myself (draw text) so I use this value for return:
return CDRF_DODEFAULT;
//Let's say I wanted to draw text and stuff, then I would have to do it before return with
//DrawText() or other function and return CDRF_SKIPDEFAULT
}
else
{
if (item->uItemState & CDIS_HOT) //Our mouse is over the button
{
//Select our color when the mouse hovers our button
if (hotbrush == NULL)
hotbrush = CreateGradientBrush(RGB(255, 230, 0), RGB(245, 0, 0), item);
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, hotbrush);
RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5);
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
return CDRF_DODEFAULT;
}
//Select our color when our button is doing nothing
if (defaultbrush == NULL)
defaultbrush = CreateGradientBrush(RGB(255, 180, 0), RGB(180, 0, 0), item);
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, defaultbrush);
RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 5, 5);
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
return CDRF_DODEFAULT;
}
}
else if (some_item->idFrom == IDC_PUSHLIKE_BUTTON && some_item->code == NM_CUSTOMDRAW)
{
LPNMCUSTOMDRAW item = (LPNMCUSTOMDRAW)some_item;
if (IsDlgButtonChecked(hwnd, some_item->idFrom))
{
if (item->uItemState & CDIS_HOT)
{
if (push_hotbrush1 == NULL)
push_hotbrush1 = CreateGradientBrush(RGB(0, 0, 245), RGB(0, 230, 255), item);
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, push_hotbrush1);
RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10);
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
return CDRF_DODEFAULT;
}
if (push_checkedbrush == NULL)
push_checkedbrush = CreateGradientBrush(RGB(0, 0, 180), RGB(0, 222, 200), item);
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, push_checkedbrush);
RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10);
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
return CDRF_DODEFAULT;
}
else
{
if (item->uItemState & CDIS_HOT)
{
if (push_hotbrush2 == NULL)
push_hotbrush2 = CreateGradientBrush(RGB(255, 230, 0), RGB(245, 0, 0), item);
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, push_hotbrush2);
RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10);
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
return CDRF_DODEFAULT;
}
if (push_uncheckedbrush == NULL)
push_uncheckedbrush = CreateGradientBrush(RGB(255, 180, 0), RGB(180, 0, 0), item);
HPEN pen = CreatePen(PS_INSIDEFRAME, 0, RGB(0, 0, 0));
HGDIOBJ old_pen = SelectObject(item->hdc, pen);
HGDIOBJ old_brush = SelectObject(item->hdc, defaultbrush);
RoundRect(item->hdc, item->rc.left, item->rc.top, item->rc.right, item->rc.bottom, 10, 10);
SelectObject(item->hdc, old_pen);
SelectObject(item->hdc, old_brush);
DeleteObject(pen);
return CDRF_DODEFAULT;
}
}
return CDRF_DODEFAULT;
}
break;
case WM_CTLCOLORBTN: //In order to make those edges invisble when we use RoundRect(),
{ //we make the color of our button's background match window's background
return (LRESULT)GetSysColorBrush(COLOR_WINDOW+1);
}
break;
case WM_CLOSE:
{
DestroyWindow(hwnd);
return 0;
}
break;
case WM_DESTROY:
{
DeleteObject(defaultbrush);
DeleteObject(selectbrush);
DeleteObject(hotbrush);
DeleteObject(push_checkedbrush);
DeleteObject(push_hotbrush1);
DeleteObject(push_hotbrush2);
DeleteObject(push_uncheckedbrush);
PostQuitMessage(0);
return 0;
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
const wchar_t ClassName[] = L"Main_Window";
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = MainWindow;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
exit(EXIT_FAILURE);
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, ClassName, L"Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 368, 248, NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
exit(EXIT_FAILURE);
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.message;
}
+0
+1 가능한 일에 대한 훌륭한 시연. 어떤 앱이라도 너무 깔끔하게 보일지 확신 할 수는 없지만, 이는 모든 종류의 맞춤형 버튼을위한 유용한 프레임 워크입니다. –
관련 문제
- 1. 버튼의 색상을 변경하는 방법
- 2. 표준 버튼의 색상을 변경하는 방법은 무엇입니까?
- 3. 선택한 바 버튼의 색상을 변경하는 방법은 무엇입니까?
- 4. UINavigationBar 및 버튼의 색상을 변경하는 방법은 무엇입니까?
- 5. 클릭 후 버튼의 색상을 변경하는 방법은 무엇입니까?
- 6. 라디오 버튼의 채우기 색상을 변경하는 방법은 무엇입니까?
- 7. SwitchButton 버튼의 색상을 변경하는 방법
- 8. ttk 버튼의 색상을 변경하는 방법
- 9. 버튼의 색상을 지우는 방법은 무엇입니까?
- 10. 버튼의 배경색을 변경하는 방법은 무엇입니까?
- 11. Android에서 XML에서 버튼의 textColor를 변경하는 방법은 무엇입니까?
- 12. 스트 라이프 팝업에서 유료 버튼의 색상을 변경하는 방법은 무엇입니까?
- 13. IE에서 비활성화 된 버튼의 텍스트 색상을 변경하는 방법은 무엇입니까?
- 14. 인라인 CSS를 사용하여 활성 상태에있는 버튼의 색상을 변경하는 방법은 무엇입니까?
- 15. silverlight에서 라디오 버튼의 도트 색상을 변경하는 방법은 무엇입니까?
- 16. Mac OS에서 내 버튼의 색상을 변경하는 방법은 무엇입니까?
- 17. 안드로이드 터치 버튼의 색상을 변경하는 방법
- 18. 프레스에서 사용자 정의 버튼의 색상을 변경하는 키브
- 19. 버튼의 색상을 지정하고 상태를 유지하는 방법은 무엇입니까?
- 20. 목록을 표시하기 위해 뒤로 버튼의 기능을 변경하는 방법은 무엇입니까?
- 21. iOS에서 버튼의 색상을 얻으려면
- 22. 위로 버튼의 기능을 비활성화하는 방법은 무엇입니까?
- 23. wpf에서 버튼의 스타일 기능을 호출하는 방법은 무엇입니까?
- 24. UIAlertView 버튼의 너비를 변경하는 방법은 무엇입니까?
- 25. 태그의 도움으로 버튼의 이미지를 변경하는 방법은 무엇입니까?
- 26. PrimeFaces onclick 버튼의 탭을 변경하는 방법은 무엇입니까?
- 27. UIActionSheet 버튼의 기본 언어를 변경하는 방법은 무엇입니까?
- 28. drupal에서 기본 버튼의 URL을 변경하는 방법은 무엇입니까?
- 29. 이 버튼의 플롯을 변경하는 방법은 무엇입니까?
- 30. 클릭하면 버튼의 글꼴을 변경하는 방법은 무엇입니까?
이 상황에서 정상적으로해야 할 일은 질문을하고 나 자신의 질문에 답하는 것입니다. 자유롭게 여기에있는 것을 편집하고 해답으로 해답을 추가하십시오. – Collin
감사합니다. 나는 미래에 그것을 명심 할 것이다. – FrogTheFrog
질문을 편집하여 다른 사람이 답을 쓸 수있는 충분한 질문이되도록하십시오 (뭔가 배울 수도 있음). 지금 귀하의 질문은 대부분 의견에 속하는 메타 토론으로 가득 차 있으며 "진정한 질문이 아님"으로 마감 될 것입니다. –