i'm trying call the WM_DRAWITEM message from WM_KEYUP message without sucess :(

bool KeyPressed(int a)
{
    if(GetAsyncKeyState(a))
    {
        return true;
    }
    else
    {
        return false;
    }
}

//in WM_KEYUP message
if(KeyPressed(VK_MENU)==true) SendMessage(hButton, WM_DRAWITEM,NULL,NULL);

what i'm doing wrong with SendMessage?

Why not just call a function that does the redrawing?

LRESULT CustomDrawButton(HWND button_hwnd, WPARAM wParam, LPARAM lParam)
{
    // drawing code goes here

    InvalidateRect(button_hwnd, NULL, FALSE); // TRUE to erase the background
    UpdateWindow(button_hwnd);

    return 0;
}

Edited 2 Years Ago by nullptr

i love your code ;)
but i get that function like a infinite loop, because of InvalidateRect() function. and i get flickers.

these code avoids the flickers, but i can't use it because can slow down the windows messages:

InvalidateRect(hButton, NULL, false); // TRUE to erase the background
            Sleep(100);
            UpdateWindow(hButton);

so what you advice more?

I did some testing and if you call InvalidateRect(hButton, NULL, false), this will cause a WM_DRAWITEM message to be sent to your control.

if (KeyPressed(VK_MENU)==true)
    InvalidateRect(hButton, NULL, false);

thanks for all..
anotherthing: when we do a draw Button, why the WM_COMMAND message is ignored?

why the WM_COMMAND message is ignored?

It shouldn't be ignored. Under what cicumstances is the message being ignored?
Post your code if you'd like someone to have a look.

heres the entire code. don't forget link the library: libuxtheme.a(i use the code blocks... see what libary is used with your IDE).

#include <windows.h>
#include <stdio.h>
#include <string>
#include <Uxtheme.h> //for use the theme functions
#include <Vsstyle.h> //for use the BP_PUSHBUTTON or others const's


using namespace std;

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
static TCHAR szAppName[] = TEXT ("RandRect") ;

HINSTANCE a;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{

    HWND hwnd ;
    MSG msg ;
    a=hInstance;
    WNDCLASS wndclass ;
    wndclass.style = 0 ;
    wndclass.lpfnWndProc = WndProc ;
    wndclass.cbClsExtra = 0 ;
    wndclass.cbWndExtra = 0 ;
    wndclass.hInstance = hInstance ;
    wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = (HBRUSH) CreateSolidBrush(RGB(0,0,255)) ;
    wndclass.lpszMenuName = NULL ;
    wndclass.lpszClassName = szAppName ;

    if (!RegisterClass (&wndclass))
    {
        MessageBox (NULL, TEXT ("This program requires Windows NT!"),szAppName, MB_ICONERROR) ;
        return 0 ;
    }

    hwnd = CreateWindowEx (0,szAppName, TEXT ("Random Rectangles"),
            WS_OVERLAPPEDWINDOW | WS_TABSTOP,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL, hInstance, NULL) ;

    ShowWindow (hwnd, iCmdShow) ;
    UpdateWindow (hwnd) ;

    while (GetMessage (&msg, NULL, 0, 0))
    {
        TranslateMessage (&msg) ;
        DispatchMessage (&msg) ;
    }
    return msg.wParam ;
}

bool KeyPressed(int a)
{
    if(GetAsyncKeyState(a))
    {
        return true;
    }
    else
    {
        return false;
    }
}

char upper(char str1)                                           //2
{

 if(str1>96 && str1<123)                           //4
       str1= str1-32;                                      //5
                                                     //6
 return str1;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    static HWND hButton;
    static HINSTANCE hInstance = GetModuleHandle(NULL);
    static HICON HandleIcon;
    static string caption="hell&o";
    static char altkey;

    switch (iMsg)
    {
        case WM_DESTROY:
            DestroyIcon(HandleIcon);
            PostQuitMessage (0) ;
            return 0 ;
        case WM_CREATE:

            //RegisterHotKey( hwnd, Hotkey_Message, MOD_CONTROL, 'A' | VK_UP );
            //create the button
            hButton=CreateWindowEx (WS_EX_TRANSPARENT ,"button", "",
            WS_CHILD | WS_VISIBLE | BS_OWNERDRAW | WS_TABSTOP | BS_NOTIFY | BS_DEFPUSHBUTTON,
            100, 100,100, 50,hwnd,NULL,hInstance, 0) ;
            for(int i=0; caption.length()-2;i++)
            {
                if(caption[i-1]!='&' && caption[i]=='&' && caption[i+1]!='&' )
                {
                    altkey=upper((char)caption[i+1]);
                    break;
                }
            }
            return 0;
        case WM_CTLCOLORBTN:
            SetBkMode( (HDC)wParam, TRANSPARENT);
                    return (LRESULT) GetStockObject(NULL_BRUSH);
        case WM_KEYUP:
            //exit the program
            if(wParam==VK_ESCAPE)
            {
                DestroyWindow(hwnd);
            }


            if (KeyPressed(VK_LMENU) && KeyPressed(altkey)) SendMessage(hButton,WM_NOTIFY,BN_CLICKED,0);
            return 0;
        case WM_HOTKEY:
            //if(wParam==Hotkey_Message) MessageBox(NULL, TEXT("hi"),TEXT("hello"), MB_OK);
                return 0;
        case WM_COMMAND:
            SetWindowText(hButton,"hi");
            return 0;
        case WM_DRAWITEM:
            // drawing code goes here
            //getting the Draw Item structure
            LPDRAWITEMSTRUCT b;
            b = (LPDRAWITEMSTRUCT) lParam;

            //Getting the button visual theme(i get the xp style)
            HTHEME hTheme;
            hTheme = OpenThemeData(hButton, L"button");

            //translate the LPDRAWITEMSTRUCT->itemState to DrawThemeBackground int id state
            int c=0;
            if(b->itemState & ODS_HOTLIGHT)
                c=PBS_HOT;
            else if (b->itemState & ODS_DEFAULT)
                c=PBS_DEFAULTED;
            else if (b->itemState & ODS_DISABLED)
                c=PBS_DISABLED;
            else if (b->itemState & ODS_SELECTED)
                c=PBS_PRESSED;
            else
                c=PBS_NORMAL;

            //draw the button with right state
            //the state is what the button action can draw to us(click,disable and others)
            DrawThemeBackground(hTheme, b->hDC, BP_PUSHBUTTON, c, &b->rcItem, 0);
            if (b->itemState & ODS_FOCUS)
            {
                SelectObject(b->hDC,CreatePen(PS_DOT,1,GetSysColor(COLOR_3DHILIGHT)));
                //RoundRect(b->hDC,4,4,b->rcItem.right-4,b->rcItem.bottom-4,5,5);
            }

            //getting and draw icon
            HICON hicon;
            hicon=LoadIcon(NULL,IDI_EXCLAMATION);
            DrawIcon(b->hDC,3,0, hicon);

            //before show the text, i need put it transparent(hide the text backcolor)
            SetBkMode(b->hDC,TRANSPARENT);

            //i can draw the text with prefix('&')
            //the DT_EXPANDTABS is for show us the '\t' and others
            if(b->itemState & ODS_NOACCEL)//if the menu key is pressed then
                DrawText(b->hDC,caption.c_str(),-1,&b->rcItem,DT_EXPANDTABS| DT_CENTER | DT_HIDEPREFIX);
            else
                DrawText(b->hDC,caption.c_str(),-1,&b->rcItem,DT_EXPANDTABS| DT_CENTER);
            return 0;
    }
    return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}

if you change the button style(delete the BS_OWNERDRAW), the WM_COMMAND and the BS_NOTIFY are used normaly

If you specify BS_OWNERDRAW then you shouldn't combine any other button styles with it.
I couldn't reproduce your problem with WM_COMMAND using VS 2012, though I did change the code to SetWindowText(hwnd, "hi");

yes.. you have right... the SetWindowText() don't works with hButton when i use BS_OWNERDRAW style.
for finish these topic, let me ask anotherthing: when i draw the button face(the WM_DRAWITEM message), why i get the windows XP visual style instead windows 98\2000 visual style?
the OpenThemeData() function is the problem?

thank you. now i can draw the windows 98 theme and windows xp theme and another drawed button... very cool... thanks for all

This question has already been answered. Start a new discussion instead.