Я теряю функциональность кнопки, когда я меняю его фон

Я пробовал каждый источник заменить фон кнопки подклассом реализации.

Когда я меняю фон, я получаю квадратную форму и невозможно щелкнуть по ней. кто-нибудь может поделиться хорошим учебником или образцом кода?

во всяком случае, это мой код:

LRESULT CALLBACK DrawPushButton(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC          hdcMem;
HBITMAP      hbmMem;
HANDLE       hnd;
PAINTSTRUCT  ps;
HDC          hdc;

int win_width=100;
int win_height=50;
    switch(uMsg)
    {
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        hdcMem = CreateCompatibleDC(hdc);
        hbmMem = CreateCompatibleBitmap(hdc, win_width, win_height);
        hnd   = SelectObject(hdcMem, hbmMem);
        BitBlt(hdc, 0, 0, win_width, win_height, hdcMem, 0, 0, SRCCOPY);
        EndPaint(hwnd, &ps);
        return 0;
        break;
    }
    return CallWindowProc (OldWndProc, hwnd, uMsg, wParam, lParam);
}

редактировать: я добавил к кнопке стиль окон BS_OWNERDRAW:

HWND hWndButton=CreateWindowEx(NULL,L"BUTTON",L"OK",WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON|BS_OWNERDRAW,50,220,100,24,hWnd,(HMENU)IDC_MAIN_BUTTON,GetModuleHandle(NULL),NULL);

и я изменил обратный вызов, но WM_DRAWITEM не вызывал:

LRESULT CALLBACK DrawPushButton(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_DRAWITEM:
            HDC hdc = GetDC(hwnd);
            TextOut(hdc,0,0,L"itay",4);
        break;
    }
    return 0;
}

person Itay Avraham    schedule 24.11.2013    source источник
comment
Чтобы вручную нарисовать кнопку, вам нужно присвоить ей стиль окна BS_OWNERDRAW, а затем обработать сообщение WM_DRAWITEM.   -  person Remy Lebeau    schedule 24.11.2013
comment
Вы не думаете, что вам следует удалять DC и Bitmap, которые вы создаете каждый раз, когда кнопка рисует?   -  person Jonathan Potter    schedule 25.11.2013
comment
@RemyLebeau Я добавил BS_OWNERDRAW, но когда я отлаживал программу, WM_DRAWITEM не вызывался. см. мой комментарий выше.   -  person Itay Avraham    schedule 25.11.2013
comment
@ItayAvraham: если вы читали документацию, WM_DRAWITEM будет отправлено в родительское окно кнопки, а не в окно кнопки.   -  person Remy Lebeau    schedule 25.11.2013
comment
@ItayAvraham: Зачем столько мучений, чтобы изменить фон кнопки? Вы можете добиться этого без подкласса. В моем ответе на этот вопрос вы можете увидеть все варианты изменения фона кнопок и реализацию некоторых из них. Надеюсь, это поможет вам. С наилучшими пожеланиями и с Рождеством.   -  person AlwaysLearningNewStuff    schedule 25.12.2013


Ответы (1)


Это не "хороший" код, хотя и функциональный - вам, вероятно, следует, как уже упоминалось, использовать стиль BS_OWNERDRAW и обрабатывать рисунок в wndproc диалогового окна/окна, содержащего кнопку. Я решил вставить старый пример, который у меня есть, который подходит к этому так же, как и вы. Вы должны сделать всю картину самостоятельно. Тем не менее, у вас есть возможность отреагировать на сообщение WM_TIMER, которое получает кнопка, что заставляет ее пульсировать. (не уверен, что у вас есть возможность сделать это, если вы рисуете только из WindowProc диалога/окна)

Я также решил использовать замененный метод подкласса для простоты. Начиная с версии 6 общих элементов управления вместо этого следует использовать SetWindowSubclass (http://msdn.microsoft.com/en-us/library/windows/desktop/bb762102(v=vs.85).aspx)

main.cpp

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"

HINSTANCE hInst;

LRESULT CALLBACK btnProc(HWND btnWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    long oldWndProc;
    int i;
    oldWndProc = GetWindowLong(btnWnd, GWL_USERDATA);
    switch (uMsg)
    {
        case WM_PAINT:
            {
                HDC hdc;
                PAINTSTRUCT ps;
                RECT mRect;
                HBRUSH mBrush;

                hdc = BeginPaint(btnWnd, &ps);
                mBrush = CreateSolidBrush( RGB(100, 147, 111));
                GetClientRect(btnWnd, &mRect);
                FillRect(hdc, &mRect, mBrush);
                DeleteObject(mBrush);

                EndPaint(btnWnd, &ps);
            }
            return 0;
    }
    return CallWindowProc((WNDPROC)oldWndProc, btnWnd, uMsg, wParam, lParam);
}


void onCommand(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
{
    switch (LOWORD(wParam))
    {
    case IDC_BUTTON1:
        MessageBeep(MB_ICONEXCLAMATION);
        break;
    }
}

LRESULT CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_INITDIALOG:
        {
            HWND btnWnd;
            long oldBtnProc;
            btnWnd = GetDlgItem(hwndDlg, IDC_BUTTON1);
            oldBtnProc = GetWindowLong(btnWnd, GWL_WNDPROC);
            SetWindowLong(btnWnd, GWL_USERDATA, oldBtnProc);
            SetWindowLong(btnWnd, GWL_WNDPROC, (long)btnProc);
        }
        return TRUE;

        case WM_CLOSE:
        {
            EndDialog(hwndDlg, 0);
        }
        return TRUE;

        case WM_COMMAND:
            onCommand(hwndDlg, wParam, lParam);
            return TRUE;
    }
    return FALSE;
}


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    hInst=hInstance;
    InitCommonControls();
    return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
}

resource.h

#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#define DLG_MAIN                                100
#define IDC_BUTTON1                             1000

resource.rc

// Generated by ResEdit 1.5.11
// Copyright (C) 2006-2012
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"

//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
DLG_MAIN DIALOG 0, 0, 186, 95
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "Ms Shell Dlg"
{
    PUSHBUTTON      "Button1", IDC_BUTTON1, 7, 7, 50, 14
}

//
// Manifest resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
1                  RT_MANIFEST    ".\\manifest.xml"

manifest.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>
person enhzflep    schedule 25.11.2013