Jump to content
KodeZwerg

How to combine a byte and a word as a hotkey word?

Recommended Posts

Hello community,

 

I have a problem where I somehow don't know the correct solution.

What I am try doing is to read out a Hotkey value from a Shortcut (.lnk) file and write it back.

 

The read out works very well and is stored that way, my problem i added aswell:

Uses Menus; // ( ShortcutToText(), TextToShortcut() )

var
 HotKeyMod: Word;
begin
// read out part is working
    HotKeyMod := Hi( SLI.HotKey );
    cbALT.Checked := ( HotKeyMod and HOTKEYF_ALT ) = HOTKEYF_ALT;
    cbCTRL.Checked := ( HotKeyMod and HOTKEYF_CONTROL ) = HOTKEYF_CONTROL;
    cbSHIFT.Checked := ( HotKeyMod and HOTKEYF_SHIFT ) = HOTKEYF_SHIFT;
    edHotKey.Text := ShortcutToText( SLI.HotKey );

// save part is not working
    HotKeyMod := 0;
    HotKeyMod := ( TextToShortcut( edHotKey.Text ) );
    if cbALT.Checked then HotKeyMod := ( HotKeyMod and HOTKEYF_ALT );
    if cbCTRL.Checked then HotKeyMod := ( HotKeyMod and HOTKEYF_CONTROL );
    if cbSHIFT.Checked then HotKeyMod := ( HotKeyMod and HOTKEYF_SHIFT );
    SLI.HotKey := HotKeyMod;
end;

I dont know how to correct put that Hi byte into that Lo Word. I tried so many combinations but not the correct one.

If someone can help, please do 🙂

Share this post


Link to post

You know the difference between the logical operators?
use  or  not and........

b := b and 1 

00000000

b := b and 2 

00000000

b := b or 1

00000001

b := b or 2

00000011

b := b or 8

00001011

b := b or 64

01001011

Share this post


Link to post
HotKeyMod := ( TextToShortcut( edHotKey.Text ) );
if cbALT.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_ALT );
if cbCTRL.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_CONTROL );
if cbSHIFT.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_SHIFT );
SLI.HotKey := (HotKeyMod SHL 8) OR (SLI.HotKey AND $FF);

 

Edited by Primož Gabrijelčič
  • Thanks 1

Share this post


Link to post

Thankyou for pointing that out, I do still have no success.

    HotKeyMod := 0;
    if cbALT.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_ALT );
    if cbCTRL.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_CONTROL );
    if cbSHIFT.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_SHIFT );
    HotKeyMod := ( HotKeyMod or TextToShortcut( edHotKey.Text ) );

 

Share this post


Link to post

I believe the modifiers are lost when translating a hotkey to a string:

 

Raw hotkey value = 0x0646
ShortCutToText() = F
TextToShortCut() = 0x0046
program Project1;

uses
  System.SysUtils,
  Vcl.Menus,
  Winapi.Windows, Winapi.CommCtrl;

procedure p();
const
	VK_F = $46;
	HOTKEYF_CTRL_ALT = (HOTKEYF_CONTROL or HOTKEYF_ALT); // Ctrl+Alt+F
var
	hotkey:	Word;
	asText:	String;
begin
	hotkey := VK_F or (HOTKEYF_CTRL_ALT shl 8);
	WriteLn('Raw hotkey value = 0x', IntToHex(hotkey, 4));

	asText := ShortCutToText(hotkey);
	WriteLn('ShortCutToText() = ', asText);

	hotkey := TextToShortCut(asText);
	WriteLn('TextToShortCut() = 0x', IntToHex(hotkey, 4));
end;

begin
	p();
	ReadLn;
end.

 

Edited by Der schöne Günther

Share this post


Link to post

My full call

uses
  LinkHelper,  // name of my helper unit
  ;

...

// here i load all
procedure TForm1.ListBox1Click(Sender: TObject);
var
 SLI: TShellLinkInfo;
 HotKeyMod: Byte;
begin
{
ShowCmd:
1 = normales fenster
3 = maximiertes fenster
7 = minimiertes fenster
}

  if ( ( ListBox1.Count > 0 ) and ( ListBox1.ItemIndex >= 0 ) ) then
  begin
    SLI := GetShellLinkInfo( ListBox1.Items[ ListBox1.ItemIndex ] );
    edPathName.Text := SLI.PathName;
    edArguments.Text := SLI.Arguments;
    edDescription.Text := SLI.Description;
    edWorkingPath.Text := SLI.WorkingDirectory;
    edIconLocation.Text := SLI.IconLocation;
    edIconIndex.Text := IntToStr( SLI.IconIndex );
    case SLI.ShowCmd of
      1: cbShowCmd.ItemIndex := 0;
      7: cbShowCmd.ItemIndex := 1;
      3: cbShowCmd.ItemIndex := 2;
      else
      cbShowCmd.ItemIndex := 0;
    end;
    edHotKey.Text := '';
    HotKeyMod := Hi( SLI.HotKey );
    cbALT.Checked := (HotKeyMod and HOTKEYF_ALT) = HOTKEYF_ALT;
    cbCTRL.Checked := (HotKeyMod and HOTKEYF_CONTROL) = HOTKEYF_CONTROL;
    cbSHIFT.Checked := (HotKeyMod and HOTKEYF_SHIFT) = HOTKEYF_SHIFT;
    edHotKey.Text := ShortcutToText( SLI.HotKey );
    btnSaveCurrent.Enabled := True;
  end;
end;

// here i save all with problem at hotkey
procedure TForm1.btnSaveCurrentClick(Sender: TObject);
var
 SLI: TShellLinkInfo;
 HotKeyMod: word;
 TBC: TWordByteConversion;
begin
  SLI.PathName := edPathName.Text;
  SLI.Arguments := edArguments.Text;
  SLI.Description := edDescription.Text;
  SLI.WorkingDirectory := edWorkingPath.Text;
  SLI.IconLocation := edIconLocation.Text;
  SLI.IconIndex := StrToInt( edIconIndex.Text );
  case cbShowCmd.ItemIndex of
    0: SLI.ShowCmd := 1;
    1: SLI.ShowCmd := 7;
    2: SLI.ShowCmd := 3;
  end;
  HotKeyMod := 0;
  HotKeyMod := ( TextToShortcut( edHotKey.Text ) );
  if cbALT.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_ALT );
  if cbCTRL.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_CONTROL );
  if cbSHIFT.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_SHIFT );
  SLI.HotKey := (HotKeyMod SHL 8) OR (HotKeyMod AND $FF); // here was error
  SetShellLinkInfo( ListBox1.Items[ ListBox1.ItemIndex ], SLI );
end;

 

Edited by KodeZwerg

Share this post


Link to post
  HotKeyMod := 0;
  if cbALT.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_ALT );
  if cbCTRL.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_CONTROL );
  if cbSHIFT.Checked then HotKeyMod := ( HotKeyMod or HOTKEYF_SHIFT );
  SLI.HotKey := (HotKeyMod SHL 8) OR ( TextToShortcut( edHotKey.Text ) AND $FF );

Success @Primož Gabrijelčič

Last line was interpreted wrong, now all works like a beauty! Thankyou for inspiration!

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×