¿Cómo se puede obtener un hijo de ComboBox de un DataGridView para procesar todas las claves, incluyendo "."?

Tengo el mismo problema que el descrito en las publicaciones que figuran a continuación. Es decir, ciertas teclas no funcionan en absoluto cuando las escribo en mi cuadro combinado hasta que presiono la barra espaciadora. Una de las teclas es ".", Pero otra es la letra "Q", y hay otras: "$", "%".

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

He intentado muchas cosas hasta ahora. Mi última falla se basó en la teoría de que tal vez DataGridView estaba usando WIN32 API wndproc subclassing para interceptar mensajes, así que escribí la lógica para guardar el viejo wndproc y restaurarlo después de agregarlo a la colección de control de DataGridView. Eso no funcionó.

Messina - gracias por recordarme sobre Spy ++. Para la letra "A", la ventana de edición envía un EN_UPDATE a su combobox principal. Pero, no para la "Q". Eso es muy extraño.

Me he convencido de que DataGridView no está subclasificando el combo y la edición, porque verifico la dirección de wndprocs justo después de la creación y antes de agregarlos a la colección de la grilla, y luego cuando pinto. A menos que la grilla instale algún tipo de gancho global ...

Estoy pensando, ¿tal vez puedo subclasificar el control de edición, y luego enviar la notificación al combobox de la misma manera que veo el control de edición aquí?

EDITAR: Más información aquí. Mensajes de Windows desde la cuadrícula, cuadro combinado y control de edición desde 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
Probé el ejemplo del foro de bytes.com, y no funcionó para mí. Me encantaría darle un giro a algunos códigos si tienes pasos de reprografía.
agregado el autor Cory Foy, fuente
Vine aquí buscando el mensaje de S: 0x2111 [Definido por el usuario: WM_USER + 7441] pero de todas formas apuesto a que puedo adivinar lo que está pasando. Las claves que te faltan ya están mapeadas. Quizás Ctrl + Q = salir. La compartición no está manejando bien las teclas rápidas.
agregado el autor John Smith, fuente

2 Respuestas

Por casualidad, ¿ya ha resuelto su problema?

Tengo el mismo problema que el suyo, mi control personalizado para DataGridView no puede recibir la letra Q, el período, el dólar, la comilla simple, el porcentaje, etc.

Pude resolver el problema cambiando el "interruptor ... predeterminado: devolver falso" a "cambiar ... predeterminado: return! DataGridViewWantsInputKey"

Supongo que el código de patrón de Microsoft para crear su propio usercontrol para datagridview no es óptimo. Este es el código de patrón de 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
agregado
No he resuelto el problema. He intentado con tu solución y eso no funciona para mí, y después de pensarlo, no estoy sorprendido. Estoy usando el cuadro combinado en el encabezado, no una celda normal. No creo que mi grid sepa lo suficiente sobre mi combobox para descubrir y usar su interfaz IDataGridViewEditingControl. Quiero decir, creo que tengo más problemas que solo este problema. Voy a marcar tu respuesta como la aceptada de todos modos.
agregado el autor Corey Trager, fuente

Respuesta parcial a mi pregunta En el cuadro combinado, manejo los eventos KeyDown, TextChanged y KeyUp, que se activan en ese orden. Si paso de KeyDown a KeyUp con TextChanged omitido, verifico si el personaje era Keys.Q o Keys.OemPeriod. (No estoy seguro de que sea seguro para otros, como shift/D1, shift/D2, etc.). Si es una de esas claves, yo mismo cambio el texto del cuadro combinado.

Pero eso no es suficiente, porque el simple hecho de cambiar el texto establece el cursor en el control de edición (que pertenece al combobox) al comienzo del texto. Entonces, para arreglarlo, uso FindWindowEx para obtener el control de edición, luego le envío un EM_SETSEL para restablecer el cursor al final de la palabra.

0
agregado