carbon: implement keyboard processing before menu fire event (LCL compatible). fixes #17205 and probably some other issues

git-svn-id: trunk@27207 -
This commit is contained in:
dmitry 2010-08-26 23:25:31 +00:00
parent 8615b73bd3
commit c9c3967f42
4 changed files with 40 additions and 11 deletions

View File

@ -84,7 +84,6 @@ type
function CheckMenu(const Menu: HMENU; const AMethodName: String; AParamName: String = ''): Boolean; function CheckMenu(const Menu: HMENU; const AMethodName: String; AParamName: String = ''): Boolean;
implementation implementation
{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
@ -769,6 +768,5 @@ begin
Result:=AnsiChar(KeyValue); Result:=AnsiChar(KeyValue);
end; end;
end. end.

View File

@ -205,7 +205,7 @@ begin
{ Another possible solution of the problem, is to Post another custom event } { Another possible solution of the problem, is to Post another custom event }
{ to the loop, and report LCL about Menu pressed after the event arrives, } { to the loop, and report LCL about Menu pressed after the event arrives, }
{ though it might seem, like interface is lagging } { though it might seem, like interface is lagging }
if (HotChar<>#0) then if (CarbonMenu.Parent.Dismissed<>kHIMenuDismissedBySelection) and (HotChar<>#0) then
begin begin
AllowMenu := True; AllowMenu := True;
Focused:=GetFocus; Focused:=GetFocus;
@ -215,17 +215,22 @@ begin
if not AllowMenu then if not AllowMenu then
begin begin
Result:=eventNotHandledErr; Result:=eventNotHandledErr;
CarbonMenu.Parent.Dismissed:=0;
Exit; Exit;
end; end;
end; end;
end; end;
if CarbonMenu.Parent.Dismissed=kHIMenuDismissedBySelection then begin
FillChar(Msg, SizeOf(Msg), 0); FillChar(Msg, SizeOf(Msg), 0);
Msg.msg := LM_ACTIVATE; Msg.msg := LM_ACTIVATE;
CarbonMenu.LCLMenuItem.Dispatch(Msg); CarbonMenu.LCLMenuItem.Dispatch(Msg);
CarbonMenu.Parent.Dismissed:=0;
Result := noErr; Result := noErr;
Exit; Exit;
end else
Result:=CallNextEventHandler(ANextHandler, AEvent);
end; end;
end; end;
end; end;

View File

@ -36,7 +36,7 @@ uses
// widgetset // widgetset
WSControls, WSLCLClasses, WSProc, WSControls, WSLCLClasses, WSProc,
// LCL Carbon // LCL Carbon
CarbonDef, CarbonGDIObjects, CarbonDef, CarbonGDIObjects, CarbonMenus,
// LCL // LCL
LMessages, LCLMessageGlue, LCLProc, LCLType, Graphics, Controls, Forms, LMessages, LCLMessageGlue, LCLProc, LCLType, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls, Menus; Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls, Menus;

View File

@ -19,6 +19,24 @@
// H A N D L E R S // H A N D L E R S
// ================================================================== // ==================================================================
procedure SendMenuActivate(AMenu: MenuRef; MenuIdx: MenuItemIndex);
var
CarbonMenu : TCarbonMenu;
Msg : TLMessage;
S : ByteCount;
begin
if GetMenuItemProperty(AMenu, MenuIdx, LAZARUS_FOURCC,
WIDGETINFO_FOURCC, SizeOf(TCarbonMenu), S, @CarbonMenu) = noErr then
begin
FillChar(Msg, SizeOf(Msg), 0);
Msg.msg := LM_ACTIVATE;
CarbonMenu.LCLMenuItem.Dispatch(Msg);
end;
end;
{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
Name: CarbonWindow_Close Name: CarbonWindow_Close
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
@ -679,6 +697,9 @@ const
KeyMsg: TLMKeyDown; KeyMsg: TLMKeyDown;
CharMsg: TLMChar; CharMsg: TLMChar;
OrigChar: AnsiString; OrigChar: AnsiString;
Menu: MenuRef;
MenuIdx: MenuItemIndex;
begin begin
Result:=EventNotHandledErr; Result:=EventNotHandledErr;
{$IFDEF VerboseKeyboard} {$IFDEF VerboseKeyboard}
@ -778,10 +799,15 @@ const
if CharMsg.CharCode<>ord(KeyChar) then if CharMsg.CharCode<>ord(KeyChar) then
LCLCharToMacEvent(Char(CharMsg.CharCode)); LCLCharToMacEvent(Char(CharMsg.CharCode));
if Result<>noErr then if Result<>noErr then
Result:=CallNextEventHandler(ANextHandler, AEvent); Result:=CallNextEventHandler(ANextHandler, AEvent);
if IsMenuKeyEvent(nil, GetCurrentEvent, kMenuEventQueryOnly, @Menu, @MenuIdx) then
begin
// re-handling menu
SendMenuActivate(Menu, MenuIdx);
end;
//Send a LM_(SYS)CHAR //Send a LM_(SYS)CHAR
if IsSysKey then if IsSysKey then
begin begin