Como você pode obter um filho ComboBox de um DataGridView para processar todas as chaves, incluindo "."?

Eu tenho o mesmo problema descrito nas postagens listadas abaixo. Ou seja, certas teclas não funcionam quando eu as digito na minha caixa de combinação até que eu primeiro acessei a barra de espaço. Uma das chaves é ".", Mas outra é a letra "Q", e há outras: "$", "%".

http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=659716&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2909173&SiteID=1&pageid=0
http://bytes.com/forum/thread548399.html

Eu tentei muitas coisas até agora. Meu último fracasso foi baseado na teoria de que talvez o DataGridView estivesse usando a subclasse WIN32 API wndproc para interceptar mensagens, então escrevi a lógica para salvar o antigo wndproc e restaurá-lo depois de adicioná-lo à coleção de controle do DataGridView. Isso não funcionou.

Messina - obrigado por me lembrar sobre o Spy ++. Para a letra "A", a janela de edição envia um EN_UPDATE para seu pai da caixa de combinação. Mas não para o "Q". Isso é tão estranho.

Eu me convenci de que o DataGridView não está subclassificando o combo e a edição, porque eu verifico o endereço do wndprocs logo após a criação e antes de adicioná-los à coleção da grade e, mais tarde, quando pinto. A menos que a grade instale algum tipo de gancho global

Eu estou pensando, talvez eu possa subclasse o controle de edição e, em seguida, enviar a notificação para o combobox a maneira como vejo o controle de edição fazendo aqui?

EDIT: mais informações aqui. Mensagens do Windows da grade, caixa de combinação e controle de edição, do Spy ++:

HWNDs: 122064e < grid 010d0674 < combobox 01360696 < combox's edit control

<01402> 01360696 P WM_KEYDOWN nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<01403> 010D0674 S WM_GETDLGCODE
<01404> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01405> 010D0674 S WM_GETDLGCODE
<01406> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01407> 010D0674 S WM_GETDLGCODE
<01408> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01409> 010D0674 S WM_GETDLGCODE
<01410> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01411> 01360696 P WM_CHAR chCharCode:'0061' (97) cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<01412> 010D0674 S WM_GETDLGCODE
<01413> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01414> 010D0674 S WM_GETDLGCODE
<01415> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS

<01416> 010D0674 S WM_COMMAND wNotifyCode:EN_UPDATE wID:1001 hwndCtl:01360696  <<< edit control sends to combobox

<01417> 010D0674 S message:0x2111 [User-defined:WM_USER+7441] wParam:00060674 lParam:010D0674    What do these do?
<01418> 010D0674 R message:0x2111 [User-defined:WM_USER+7441] lResult:00000000

<01419> 010D0674 R WM_COMMAND
<01420> 010D0674 S WM_CTLCOLOREDIT hdcEdit:C7011AA6 hwndEdit:01360696
<01421> 010D0674 R WM_CTLCOLOREDIT hBrush:F0103EB0

<01422> 010D0674 S WM_COMMAND wNotifyCode:EN_CHANGE wID:1001 hwndCtl:01360696  << edit control sends to combobox

<01423> 010D0674 S message:0x2111 [User-defined:WM_USER+7441] wParam:00050674 lParam:010D0674

<01424> 0122064E S WM_PAINT hdc:00000000   <<< grid is told to paint
<01425> 0122064E S WM_ERASEBKGND hdc:94011D4E
<01426> 0122064E R WM_ERASEBKGND fErased:True
<01427> 0122064E S WM_GETTEXTLENGTH
<01428> 0122064E R WM_GETTEXTLENGTH cch:0
<01429> 0122064E S WM_GETTEXT cchTextMax:2 lpszText:0012D0C0
<01430> 0122064E R WM_GETTEXT cchCopied:0 lpszText:0012D0C0 ("")
<01431> 0122064E S WM_GETTEXTLENGTH
<01432> 0122064E R WM_GETTEXTLENGTH cch:0
<01433> 0122064E S WM_GETTEXT cchTextMax:2 lpszText:0012D0C0
<01434> 0122064E R WM_GETTEXT cchCopied:0 lpszText:0012D0C0 ("")
<01435> 010D0674 S WM_WINDOWPOSCHANGING lpwp:0012D4B0
<01436> 010D0674 R WM_WINDOWPOSCHANGING
<01437> 010D0674 S CB_GETCURSEL
<01438> 010D0674 R CB_GETCURSEL index:CB_ERR
<01439> 010D0674 S WM_GETTEXTLENGTH
<01440> 01360696 S WM_GETTEXTLENGTH
<01441> 01360696 R WM_GETTEXTLENGTH cch:2
<01442> 010D0674 R WM_GETTEXTLENGTH cch:2
<01443> 010D0674 S WM_GETTEXT cchTextMax:6 lpszText:0012CC44
<01444> 01360696 S WM_GETTEXT cchTextMax:6 lpszText:0012BE64
<01445> 01360696 R WM_GETTEXT cchCopied:2 lpszText:0012BE64 ("a")
<01446> 010D0674 R WM_GETTEXT cchCopied:2 lpszText:0012CC44 ("a")
<01447> 010D0674 S CB_GETCURSEL
<01448> 010D0674 R CB_GETCURSEL index:CB_ERR
<01449> 010D0674 S WM_GETTEXTLENGTH
<01450> 01360696 S WM_GETTEXTLENGTH
<01451> 01360696 R WM_GETTEXTLENGTH cch:2
<01452> 010D0674 R WM_GETTEXTLENGTH cch:2
<01453> 010D0674 S WM_GETTEXT cchTextMax:6 lpszText:0012CC44
<01454> 01360696 S WM_GETTEXT cchTextMax:6 lpszText:0012BE64
<01455> 01360696 R WM_GETTEXT cchCopied:2 lpszText:0012BE64 ("a")
<01456> 010D0674 R WM_GETTEXT cchCopied:2 lpszText:0012CC44 ("a")
<01457> 010D0674 S CB_GETCURSEL
<01458> 010D0674 R CB_GETCURSEL index:CB_ERR
<01531> 0122064E R WM_PAINT
<01532> 010D0674 S WM_PAINT hdc:00000000
<01533> 010D0674 S WM_NCPAINT hrgn:00000001
<01534> 010D0674 R WM_NCPAINT
<01535> 010D0674 S WM_ERASEBKGND hdc:0F0141ED
<01536> 010D0674 R WM_ERASEBKGND fErased:True
<01537> 0122064E S WM_CTLCOLOREDIT hdcEdit:840137F1 hwndEdit:010D0674
<01538> 0122064E R WM_CTLCOLOREDIT hBrush:F0103EB0
<01539> 010D0674 R WM_PAINT
<01540> 01360696 S WM_PAINT hdc:00000000
<01541> 01360696 S WM_NCPAINT hrgn:00000001
<01542> 01360696 R WM_NCPAINT
<01543> 01360696 S WM_ERASEBKGND hdc:C7011AA6
<01544> 01360696 R WM_ERASEBKGND fErased:True
<01545> 010D0674 S WM_CTLCOLOREDIT hdcEdit:870137F1 hwndEdit:01360696
<01546> 010D0674 R WM_CTLCOLOREDIT hBrush:F0103EB0
<01547> 010D0674 S WM_CTLCOLOREDIT hdcEdit:870137F1 hwndEdit:01360696
<01548> 010D0674 R WM_CTLCOLOREDIT hBrush:F0103EB0
<01549> 01360696 R WM_PAINT
<01555> 0122064E S WM_CTLCOLOREDIT hdcEdit:8A0137F1 hwndEdit:010306AC
<01556> 0122064E R WM_CTLCOLOREDIT hBrush:78103C5B
<01568> 010D0674 S CB_GETCURSEL
<01569> 010D0674 R CB_GETCURSEL index:CB_ERR
<01570> 010D0674 S WM_GETTEXTLENGTH
<01571> 01360696 S WM_GETTEXTLENGTH
<01572> 01360696 R WM_GETTEXTLENGTH cch:2
<01573> 010D0674 R WM_GETTEXTLENGTH cch:2
<01574> 010D0674 S WM_GETTEXT cchTextMax:6 lpszText:0012D7A4
<01575> 01360696 S WM_GETTEXT cchTextMax:6 lpszText:0012C9C4
<01576> 01360696 R WM_GETTEXT cchCopied:2 lpszText:0012C9C4 ("a")
<01577> 010D0674 R WM_GETTEXT cchCopied:2 lpszText:0012D7A4 ("a")
<01578> 010D0674 S CB_GETCURSEL
<01579> 010D0674 R CB_GETCURSEL index:CB_ERR
<01580> 010D0674 S WM_GETTEXTLENGTH
<01581> 01360696 S WM_GETTEXTLENGTH
<01582> 01360696 R WM_GETTEXTLENGTH cch:2
<01583> 010D0674 R WM_GETTEXTLENGTH cch:2
<01584> 010D0674 S WM_GETTEXT cchTextMax:6 lpszText:0012D6E0
<01585> 01360696 S WM_GETTEXT cchTextMax:6 lpszText:0012C900
<01586> 01360696 R WM_GETTEXT cchCopied:2 lpszText:0012C900 ("a")
<01587> 010D0674 R WM_GETTEXT cchCopied:2 lpszText:0012D6E0 ("a")
<01588> 010D0674 S CB_GETCURSEL
<01589> 010D0674 R CB_GETCURSEL index:CB_ERR
<01590> 010D0674 S WM_GETTEXTLENGTH
<01591> 01360696 S WM_GETTEXTLENGTH
<01592> 01360696 R WM_GETTEXTLENGTH cch:2
<01593> 010D0674 R WM_GETTEXTLENGTH cch:2
<01594> 010D0674 S WM_GETTEXT cchTextMax:6 lpszText:0012D6E0
<01595> 01360696 S WM_GETTEXT cchTextMax:6 lpszText:0012C900
<01596> 01360696 R WM_GETTEXT cchCopied:2 lpszText:0012C900 ("a")
<01597> 010D0674 R WM_GETTEXT cchCopied:2 lpszText:0012D6E0 ("a")
<01598> 010D0674 R message:0x2111 [User-defined:WM_USER+7441] lResult:00000000
<01599> 01360696 S WM_GETTEXTLENGTH
<01600> 01360696 R WM_GETTEXTLENGTH cch:2
<01601> 01360696 S WM_GETTEXT cchTextMax:6 lpszText:0012DF8C
<01602> 01360696 R WM_GETTEXT cchCopied:2 lpszText:0012DF8C ("a")
<01603> 010D0674 R WM_COMMAND
<01604> 01360696 P WM_KEYUP nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:1

Letra q

<01625> 01360696 P WM_KEYDOWN nVirtKey:'Q' cRepeat:1 ScanCode:10 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<01626> 010D0674 S WM_GETDLGCODE
<01627> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01628> 010D0674 S WM_GETDLGCODE
<01629> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01630> 010D0674 S WM_GETDLGCODE
<01631> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01632> 010D0674 S WM_GETDLGCODE
<01633> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01634> 01360696 P WM_CHAR chCharCode:'0071' (113) cRepeat:1 ScanCode:10 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<01635> 010D0674 S WM_GETDLGCODE
<01636> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01637> 010D0674 S WM_GETDLGCODE
<01638> 010D0674 R WM_GETDLGCODE fuDlgCode:DLGC_WANTARROWS | DLGC_WANTCHARS
<01640> 01360696 P WM_KEYUP nVirtKey:'Q' cRepeat:1 ScanCode:10 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
1
Eu tentei o exemplo do fórum bytes.com, e não funcionou para mim. Eu ficaria feliz em dar um pouco de código se você tiver etapas de repro.
adicionado o autor Cory Foy, fonte
Eu vim aqui procurando pela mensagem S: 0x2111 [User-defined: WM_USER + 7441] mas enfim aposto que posso adivinhar o que está acontecendo. As chaves que você está perdendo já estão mapeadas. Talvez Ctrl + Q = saia. A combox não está lidando bem com teclas de atalho.
adicionado o autor John Smith, fonte

2 Respostas

Por acaso, você já resolveu seu problema?

Eu tenho o mesmo problema que o seu, meu controle personalizado para DataGridView não pode receber letra Q, período, dólar, aspas simples, porcentagem, etc.

Consegui resolver o problema alterando o "switch .. default: return false" para "switch .. default: return! DataGridViewWantsInputKey"

Eu acho que o código padrão da Microsoft para fazer o seu próprio usercontrol para datagridview não é o ideal. Este é o código padrão da Microsoft:

http://msdn.microsoft.com/en-au /library/7tas5c80(vs.80))aspx

public bool EditingControlWantsInputKey(
    Keys key, bool dataGridViewWantsInputKey)
{
   //Let the DateTimePicker handle the keys listed.
    switch (key & Keys.KeyCode)
    {
        case Keys.Left:
        case Keys.Up:
        case Keys.Down:
        case Keys.Right:
        case Keys.Home:
        case Keys.End:
        case Keys.PageDown:
        case Keys.PageUp:
            return true;
        default:
            return false;//I changed this to: return !dataGridViewWantsInputKey.  My usercontrol can now receive Q, period, dollar, etc.
    }
}
1
adicionado
Eu não resolvi o problema. Eu tentei a sua solução e isso não está funcionando para mim, e depois de pensar sobre isso, não estou surpreso. Estou usando a caixa de combinação no cabeçalho, não uma célula normal. Eu não acho que minha grade sabe o suficiente sobre minha caixa de combinação para descobrir e usar sua interface IDataGridViewEditingControl. Quero dizer, acho que tenho mais problemas do que apenas esse problema. Vou marcar sua resposta como a aceita mesmo assim.
adicionado o autor Corey Trager, fonte

Resposta parcial à minha pergunta. No Combobox eu manipulo os eventos KeyDown, TextChanged e KeyUp, que são disparados nessa ordem. Se eu passar de KeyDown para KeyUp com TextChanged ignorado, eu verifico se o caractere era um Keys.Q ou Keys.OemPeriod. (Eu não tenho certeza se é seguro para os outros, como shift/D1, shift/D2, etc ...). Se é uma daquelas chaves, eu mudo o texto da combobox eu mesmo.

Mas isso não é suficiente, porque apenas alterar o texto define o cursor no controle de edição (que pertence à caixa de combinação) para o início do texto. Então, para corrigir isso, eu uso FindWindowEx para obter o identificador do controle de edição, em seguida, envie um EM_SETSEL para redefinir o cursor para o final da palavra.

0
adicionado