Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SendMessage - WM_CHAR or WM_KEYDOWN

1,903 views
Skip to first unread message

Mike

unread,
Jun 16, 2005, 4:32:03 AM6/16/05
to
Hi,
IDE: Delphi6
Issue: I have a form where there are at least two controls in no
parent/owner -
child relationship. It's about a TDBGrid and a TDateTimePicker.
One of them should "inform" the other abut a KeyDown event.

The quest is to drop the TDateTimePicker drop-down list in a programmatic
way.
More specific: when an event of type OnKeydown occurs at the TDBGrid level,
this should force the drop-down list of TDateTimePicker control to drop.

I've thought of sending a message (WM_CHAR) to TDateTimePicker control
across
"SendMessage" but there are some questions:
1. What value should have the fourth parameter (lParam) of SendMessage in
order to "inform" the control that Alt key is pressed
2. Is it enough to send below message in order to have the drop-down list
dropped:
"SendMessage(lDateTimePicker.Handle, WM_CHAR, word(Key), ...);"?

I should add that this happens in an OnKeyDown event.

I'll be grateful to anyone who'll suggest a better way!
Mike


Peter Below (TeamB)

unread,
Jun 16, 2005, 1:30:36 PM6/16/05
to
In article <42b1390c$1...@newsgroups.borland.com>, Mike wrote:
> IDE: Delphi6
> Issue: I have a form where there are at least two controls in no
> parent/owner -
> child relationship. It's about a TDBGrid and a TDateTimePicker.
> One of them should "inform" the other abut a KeyDown event.
>
> The quest is to drop the TDateTimePicker drop-down list in a programmatic
> way.

You can do that by sending it an Alt-Down arrow key sequence:


Procedure PostKeyEx( hWindow: HWnd; key: Word; Const shift: TShiftState;
specialkey: Boolean );
Type
TBuffers = Array [0..1] of TKeyboardState;
Var
pKeyBuffers : ^TBuffers;
lparam: LongInt;
Begin
(* check if the target window exists *)
If IsWindow(hWindow) Then Begin
(* set local variables to default values *)
pKeyBuffers := Nil;
lparam := MakeLong(0, MapVirtualKey(key, 0));

(* modify lparam if special key requested *)
If specialkey Then
lparam := lparam or $1000000;

(* allocate space for the key state buffers *)
New(pKeyBuffers);
try
(* Fill buffer 1 with current state so we can later restore it.
Null out buffer 0 to get a "no key pressed" state. *)
GetKeyboardState( pKeyBuffers^[1] );
FillChar(pKeyBuffers^[0], Sizeof(TKeyboardState), 0);

(* set the requested modifier keys to "down" state in the buffer *)
If ssShift In shift Then
pKeyBuffers^[0][VK_SHIFT] := $80;
If ssAlt In shift Then Begin
(* Alt needs special treatment since a bit in lparam needs also be
set *)
pKeyBuffers^[0][VK_MENU] := $80;
lparam := lparam or $20000000;
End;
If ssCtrl In shift Then
pKeyBuffers^[0][VK_CONTROL] := $80;
If ssLeft In shift Then
pKeyBuffers^[0][VK_LBUTTON] := $80;
If ssRight In shift Then
pKeyBuffers^[0][VK_RBUTTON] := $80;
If ssMiddle In shift Then
pKeyBuffers^[0][VK_MBUTTON] := $80;

(* make out new key state array the active key state map *)
SetKeyboardState( pKeyBuffers^[0] );

(* post the key messages *)
If ssAlt In Shift Then Begin
PostMessage( hWindow, WM_SYSKEYDOWN, key, lparam);
PostMessage( hWindow, WM_SYSKEYUP, key, lparam or $C0000000);
End
Else Begin
PostMessage( hWindow, WM_KEYDOWN, key, lparam);
PostMessage( hWindow, WM_KEYUP, key, lparam or $C0000000);
End;
(* process the messages *)
Application.ProcessMessages;

(* restore the old key state map *)
SetKeyboardState( pKeyBuffers^[1] );
finally
(* free the memory for the key state buffers *)
If pKeyBuffers <> Nil Then
Dispose( pKeyBuffers );
End; { finally }
End;
End; { PostKeyEx }

procedure TForm1.Button2Click(Sender: TObject);
begin
PostKeyEx(Datetimepicker1.Handle, VK_DOWN, [ssAlt], false);
end;

--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be


0 new messages