creating a custom draw hotkey control

I need to custom draw a hotkey control.
the hotkey control from windows common controls does not support custom drawing.
does anyone know how to draw such a control? (to make the control have a skin, something diffrent from the basic rectangular shape the windows common controls have)
LVL 11
AgariciAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DanRollinsCommented:
HOTKEY_CLASS supports niether CustomDraw nor OwnerDraw.  That measn that you will need to subclass the window and provide WM_PAINT and perhaps WM_NCPAINT if you want it to look other than an EditBox.  

Note that at least some styles work to set the boder to indented or raised or whatever.  But I'm gueesing you want more hands-on control over the appearance.  That measn you need to go back-to-basics and handle the low-level paointing.

An alternative would be to make it an Edit Control and just capture all keystrokes and etc to simulate what a hotkey control does.

-- Dan
0
AgariciAuthor Commented:
hello DanRollins,
first thank yo for the comment.

then:
- I tried painting the control window but I have a problem: in wm_paint I also have to display the text ( the current key combination ) and I can't get it from the control; of corse one can obtain the selected key combination but that means I have to format the displayed string myself.
- painting the window ( client or non client area ) will not change the shape of my control, so I will try to set a region to the control window but then it will be necesary to paint the text in the window ...

- about simulating the funcionality of a hotkey control in an edit control, I also thouhgt about it but it seems like reiventing the wheel.( eventualy, if nothing else works, maybe)

so if you know some method for obtaining the text I would appreciate the help.


Agarici.
0
AgariciAuthor Commented:
hello DanRollins,
first thank yo for the comment.

then:
- I tried painting the control window but I have a problem: in wm_paint I also have to display the text ( the current key combination ) and I can't get it from the control; of corse one can obtain the selected key combination but that means I have to format the displayed string myself.
- painting the window ( client or non client area ) will not change the shape of my control, so I will try to set a region to the control window but then it will be necesary to paint the text in the window ...

- about simulating the funcionality of a hotkey control in an edit control, I also thouhgt about it but it seems like reiventing the wheel.( eventualy, if nothing else works, maybe)

so if you know some method for obtaining the text I would appreciate the help.


Agarici.
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

DanRollinsCommented:
>>I also have to display the text ( the current key combination ) and I can't get it from the control;

Since the control normally displays that text (for instance, "SHIFT+CTRL+Q" ), it certainly should be available to you.  What does GetWindowText or GetDlgItemText return?  If calling those functions during WM_PAINT returns no text, then try calling sometime after the first WM_PAINT (the window text may not be set immediately after the keystroke has been pressed).

-- Dan
0
AgariciAuthor Commented:
GetWindowText and GetDlgItemText always return an empty string ( that is why I said I can't get it).

Now, that you said the text may not be set immediately, i tryed geting it at a moment I was sure it was set... also an empty sring!

I dont know what to make of it... Is the text in the hotkey control only drawn?

maybe I make a mistake somewere in the source code, but the code for doing this is not so dificult to rise such mistakes.

let me elaborate a litle :
I made a dialog and put a hotkey control in it ( hotkey ctrl ID is IDC_HOTKEY1); then I added a button on which I tried to get the control text:

void CXprjDlg::OnButton1()
{
     // TODO: Add your control notification handler code here
     char str[50];
     //int n = GetDlgItemText(IDC_HOTKEY1,str,50);
     int n = ::GetWindowText(GetDlgItem(IDC_HOTKEY1)->m_hWnd,str,50);
     MessageBox( str );
}

is there something wrong in this code?



A.
0
DanRollinsCommented:
You are right.  It is not returning WindowText, regardless of the method.  Strange.  However, I hacked together a quick lookup table.  You can probably improve it...


void CD06Dlg::OnButton1()
{
      CString s;
      m_ctlHotKey.GetWindowText( s );  // fails!
      GetDlgItemText(IDC_HOTKEY1, s ); // fails!

      WORD wVirtualKeyCode, wModifiers;
      m_ctlHotKey.GetHotKey( wVirtualKeyCode, wModifiers );
      CString sKeyName= GetModifierText( wModifiers );
      if (sKeyName > "" ) sKeyName += " + ";
      sKeyName += GetVirtualKeyCodeText( wVirtualKeyCode, wModifiers );
      MessageBox( sKeyName);
}


CString GetModifierText( WORD nModifiers )
{
      CString sRet="";
      if ( nModifiers & HOTKEYF_CONTROL ) sRet += "Ctrl + ";
      if ( nModifiers & HOTKEYF_SHIFT   ) sRet += "Shift + ";
      if ( nModifiers & HOTKEYF_ALT     ) sRet += "Alt + ";
//      if ( nModifiers & HOTKEYF_EXT     ) sRet += "Ext + ";  // whas is dis!

      sRet.TrimRight(" +");
      return( sRet );
}


#define M_KeyCase(s) case VK_##s: return #s;
#define M_KeyName(k,s) case VK_##k: return #s;

const char* GetVirtualKeyCodeText( WORD n, WORD nModifiers )
{
      static char szKeyName[5];
      switch( n ) {
            default:
                  if (n >= 0xd0 ) n -= 0x80;
                  if (n >= 0xc0 ) n -= 0x60;
                  if (n >= 0xb0 ) n -= 0x90;
                  wsprintf(szKeyName,"%c", n );
            return( szKeyName );

            case 0xba:     return ";" ; // a few special cases
            case 0xbb:     return "=" ; //
            case 0xde:     return "'" ; //

            M_KeyCase( LBUTTON       ); // 0x01
            M_KeyCase( RBUTTON       ); // 0x02
            M_KeyCase( CANCEL        ); // 0x03
            M_KeyCase( MBUTTON       ); // 0x04    /* NOT contiguous with L & RBUTTON */

            M_KeyCase( BACK          ); // 0x08
            M_KeyCase( TAB           ); // 0x09

            M_KeyCase( CLEAR         ); // 0x0C
            M_KeyCase( RETURN        ); // 0x0D

            M_KeyCase( SHIFT         ); // 0x10
            M_KeyCase( CONTROL       ); // 0x11
            M_KeyCase( MENU          ); // 0x12
            M_KeyCase( PAUSE         ); // 0x13
            M_KeyCase( CAPITAL       ); // 0x14

            M_KeyCase( KANA          ); // 0x15
            //M_KeyCase( HANGEUL     ); // 0x15  // dup
            //M_KeyCase( HANGUL      ); // 0x15  // dup
            M_KeyCase( JUNJA         ); // 0x17
            M_KeyCase( FINAL         ); // 0x18
            M_KeyCase( HANJA         ); // 0x19
            //M_KeyCase( KANJI       ); // 0x19  // dup

            M_KeyCase( ESCAPE        ); // 0x1B

            M_KeyCase( CONVERT       ); // 0x1C
            M_KeyCase( NONCONVERT    ); // 0x1D
            M_KeyCase( ACCEPT        ); // 0x1E
            M_KeyCase( MODECHANGE    ); // 0x1F

            M_KeyCase( SPACE         ); // 0x20
            M_KeyName( PRIOR, "PgUp" ); // 0x21
            M_KeyName( NEXT, "PgDn"  ); // 0x22
            M_KeyCase( END           ); // 0x23
            M_KeyCase( HOME          ); // 0x24
            M_KeyCase( LEFT          ); // 0x25
            M_KeyCase( UP            ); // 0x26
            M_KeyCase( RIGHT         ); // 0x27
            M_KeyCase( DOWN          ); // 0x28
            M_KeyCase( SELECT        ); // 0x29
            M_KeyCase( PRINT         ); // 0x2A
            M_KeyCase( EXECUTE       ); // 0x2B
            M_KeyCase( SNAPSHOT      ); // 0x2C
            M_KeyCase( INSERT        ); // 0x2D
            M_KeyCase( DELETE        ); // 0x2E
            M_KeyCase( HELP          ); // 0x2F

            M_KeyCase( LWIN          ); // 0x5B
            M_KeyCase( RWIN          ); // 0x5C
            M_KeyCase( APPS          ); // 0x5D

            M_KeyCase( NUMPAD0       ); // 0x60
            M_KeyCase( NUMPAD1       ); // 0x61
            M_KeyCase( NUMPAD2       ); // 0x62
            M_KeyCase( NUMPAD3       ); // 0x63
            M_KeyCase( NUMPAD4       ); // 0x64
            M_KeyCase( NUMPAD5       ); // 0x65
            M_KeyCase( NUMPAD6       ); // 0x66
            M_KeyCase( NUMPAD7       ); // 0x67
            M_KeyCase( NUMPAD8       ); // 0x68
            M_KeyCase( NUMPAD9       ); // 0x69
            M_KeyCase( MULTIPLY      ); // 0x6A
            M_KeyCase( ADD           ); // 0x6B
            M_KeyCase( SEPARATOR     ); // 0x6C
            M_KeyCase( SUBTRACT      ); // 0x6D
            M_KeyCase( DECIMAL       ); // 0x6E
            M_KeyCase( DIVIDE        ); // 0x6F
            M_KeyCase( F1            ); // 0x70
            M_KeyCase( F2            ); // 0x71
            M_KeyCase( F3            ); // 0x72
            M_KeyCase( F4            ); // 0x73
            M_KeyCase( F5            ); // 0x74
            M_KeyCase( F6            ); // 0x75
            M_KeyCase( F7            ); // 0x76
            M_KeyCase( F8            ); // 0x77
            M_KeyCase( F9            ); // 0x78
            M_KeyCase( F10           ); // 0x79
            M_KeyCase( F11           ); // 0x7A
            M_KeyCase( F12           ); // 0x7B
            M_KeyCase( F13           ); // 0x7C
            M_KeyCase( F14           ); // 0x7D
            M_KeyCase( F15           ); // 0x7E
            M_KeyCase( F16           ); // 0x7F
            M_KeyCase( F17           ); // 0x80
            M_KeyCase( F18           ); // 0x81
            M_KeyCase( F19           ); // 0x82
            M_KeyCase( F20           ); // 0x83
            M_KeyCase( F21           ); // 0x84
            M_KeyCase( F22           ); // 0x85
            M_KeyCase( F23           ); // 0x86
            M_KeyCase( F24           ); // 0x87

            M_KeyCase( NUMLOCK       ); // 0x90
            M_KeyCase( SCROLL        ); // 0x91


            M_KeyCase( ATTN          ); // 0xF6
            M_KeyCase( CRSEL         ); // 0xF7
            M_KeyCase( EXSEL         ); // 0xF8
            M_KeyCase( EREOF         ); // 0xF9
            M_KeyCase( PLAY          ); // 0xFA
            M_KeyCase( ZOOM          ); // 0xFB
            M_KeyCase( NONAME        ); // 0xFC
            M_KeyCase( PA1           ); // 0xFD
            M_KeyCase( OEM_CLEAR     ); // 0xFE
      }
}
0
AgariciAuthor Commented:
(nice piece of code, I like it!)
thank you for helping me, DanRollins.
0
DanRollinsCommented:
Glad to help!
The best way to thank an expert here at EE is to click the "Accept Comment as Answer" link near a comment, then click the "Excellent" radio button, then click [Submit].

-- Dan
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.