Recent

Author Topic: language change notification  (Read 20928 times)

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: language change notification
« Reply #15 on: January 02, 2014, 03:52:48 pm »
@Paskal thanks for the suggestions, somehow it makes sense to have the 1st 4 characters of a PAnsiChar set to null. there are a number of ways to do that in lazarus eg the fillchar procedure.

@HowardPC noted thanks for the report.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: language change notification
« Reply #16 on: January 03, 2014, 07:59:46 am »
There is a bug in Windows XP- instead of setting the keyboard layout globally, it set's it separately for each thread. Practically I never know which is my current layout, so I just start typing, if needed I delete the typed chars, then I switch the layouts and start typing again.
For me it will be useful to have a status window/bar somewhere on the screen (I keep the taskbar autohidden and often it does not want to unhide).
So if I get things right, I have to use GetKeyboardLayout(idThread); where idThread is the thread number of the desired thread. In my case it should be the active thread.
I tried to use GetKeyboardLayout(GetThreadID); in a timer event, but is seems that GetThreadID returns the number of the thread of the host application, not of the windows active application.
Can anyone tell me how to get the ID of the thread of the active application in Windows?
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: language change notification
« Reply #17 on: January 03, 2014, 08:13:08 am »
Quote
Parameters
idThread [in]
    Type: DWORD\
    The identifier of the thread to query, or 0 for the current thread.
using GetKeyboardLayout(0); will return the layout for the thread that called the function since all GUI components are in a single thread it will return the layout of your application.If you use it in any LCL Control event including a ttimer.onTimer event.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

CM630

  • Hero Member
  • *****
  • Posts: 1091
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: language change notification
« Reply #18 on: January 03, 2014, 08:55:33 am »
I had no idea, that all GUI components are in a single thread.
Anyway, my idea is i.e. I am typing in the browser, and I want the status bar to display the keyboard layout of the focused apllication (the browser).
So I have to get the thread ID of the browser main windows and to put it in GetKeyboardLayout(ThreadID);
The question is how to get the ThreadID of the browser (whatever other app).


BTW, I think there is a mistake in http://lazarus-ccr.sourceforge.net/docs/rtl/system/getthreadid.html . It says GetThreadID returns the current process ID instead of GetThreadID returns the current thread ID. Whom shall I tel l to fix it?
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: language change notification
« Reply #19 on: January 09, 2014, 07:46:27 am »
@Taazz, You might want to know about using hooks to receive language change notifications. Of course, may be you are already familiar with them and they are limited to Windows:
Code: [Select]
uses
  ..., Windows;
..
var
  ShellHookHandle: HHOOK;
..
function LanguageChangeHook(nCode: longint; wParam: WPARAM; lParam: LParam): HRESULT; stdcall;
begin
  if nCode = HSHELL_LANGUAGE then
  begin
    //Here goes your code
  end;
  Result := CallNextHookEx(ShellHookHandle, nCode, wParam, lParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ShellHookHandle := SetWindowsHookEx(WH_SHELL, @LanguageChangeHook, 0, GetCurrentThreadId);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if ShellHookHandle<>0 then
  begin
    UnhookWindowsHookEx(ShellHookHandle);
    ShellHookHandle := 0;
  end;
end;

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: language change notification
« Reply #20 on: January 09, 2014, 07:47:34 am »
Can anyone tell me how to get the ID of the thread of the active application in Windows?
The question is how to get the ThreadID of the browser (whatever other app).

@paskal, Find the foreground window, then get its thread ID. I assume something like this:
Code: [Select]
uses
  ..., Windows;
..
var
  TargetThreadId: DWord;
..
  TargetThreadId := GetWindowThreadProcessId(GetForegroundWindow, nil);

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: language change notification
« Reply #21 on: February 07, 2014, 04:07:36 pm »
I was bored today and didn't want to work so I patched some of my components and corrected the bugs reported for the statusbar. It should be stable enough now for your tests if any thing new comes up please post it here. It does require a good cleanup but I'm doing only patchwork today.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: language change notification
« Reply #22 on: February 07, 2014, 06:13:44 pm »
Quote
Date last modified:  November 27, 2000

I think you forgot to put m_iIconSize instead of 20 for icon width.

Code: [Select]
procedure TEvsStatusBar.Paint;
..
            case p.HAlignment of
              taCenter:
                begin
..
                  iX := tCR.Right - tCR.Left + m_iIconSize;  //20;

You might want to get rid of this small unreachable code as well?
Code: [Select]
procedure TEvsStatusBar.Paint;
...
  if SimplePanel then begin
..
  end else
..
      if (SimplePanel) then       //  Always false?
        tBR.Right := tOR.Right  //  Unreachable code
      else

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: language change notification
« Reply #23 on: February 07, 2014, 06:30:32 pm »
Quote
Date last modified:  November 27, 2000

I think you forgot to put m_iIconSize instead of 20 for icon width.

Code: [Select]
procedure TEvsStatusBar.Paint;
..
            case p.HAlignment of
              taCenter:
                begin
..
                  iX := tCR.Right - tCR.Left + m_iIconSize;  //20;

Ehmm, no a few lines down you should have.

Code: [Select]
                  iX := tCR.Right - tCR.Left + 20;
                  iX := tBR.Left + ((tBR.Right - tBR.Left) - iX) div 2;
                  Images.Draw(b.Canvas, iX, iY, p.ImageIndex);
                  tBR.Left := iX + m_iIconSize + 4;
as you can see m_iIconSize is added on the line above so the 20 above has an other meaning which I haven't got the smallest idea of why it is needed at this point.


You might want to get rid of this small unreachable code as well?
Code: [Select]
procedure TEvsStatusBar.Paint;
...
  if SimplePanel then begin
..
  end else
..
      if (SimplePanel) then       //  Always false?
        tBR.Right := tOR.Right  //  Unreachable code
      else
Now why didn't I see that at all? In any case done and scratching my head. Oh well until the next time.
thank you for the input.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: language change notification
« Reply #24 on: February 07, 2014, 06:45:45 pm »
Ehmm, no a few lines down you should have.

Code: [Select]
                  iX := tCR.Right - tCR.Left + 20;
                  iX := tBR.Left + ((tBR.Right - tBR.Left) - iX) div 2;
                  Images.Draw(b.Canvas, iX, iY, p.ImageIndex);
                  tBR.Left := iX + m_iIconSize + 4;
as you can see m_iIconSize is added on the line above so the 20 above has an other meaning which I haven't got the smallest idea of why it is needed at this point.
You used this value to center your icon. I discovered this typo when I noticed that the icons were not centered. Again, change this 20 to m_iIconSize and don't argue with me.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: language change notification
« Reply #25 on: February 07, 2014, 07:18:06 pm »
Ehmm, no a few lines down you should have.

Code: [Select]
                  iX := tCR.Right - tCR.Left + 20;
                  iX := tBR.Left + ((tBR.Right - tBR.Left) - iX) div 2;
                  Images.Draw(b.Canvas, iX, iY, p.ImageIndex);
                  tBR.Left := iX + m_iIconSize + 4;
as you can see m_iIconSize is added on the line above so the 20 above has an other meaning which I haven't got the smallest idea of why it is needed at this point.
You used this value to center your icon. I discovered this typo when I noticed that the icons were not centered. Again, change this 20 to m_iIconSize and don't argue with me.
LOL
sorry this is not how I do things  :P I have already added your comments to the clean up task list and I'll probably find out that you are right but until then...
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: language change notification
« Reply #26 on: February 07, 2014, 09:05:23 pm »
... and don't argue with me.
LOL
sorry this is not how I do things  :P I have already added your comments to the clean up task list and I'll probably find out that you are right but until then...
I'm glad that you realized that I'm joking.  Now since you showed some flexibility, that value is dependent on whether we do have text or not, so it should be changed from:
Code: [Select]
                  if p.Text <> '' then
                    DrawText(b.Canvas.Handle, PChar(p.Text), Length(p.Text), tCR, DT_CALCRECT)
                  else
                    tCR := Classes.Rect(0, 0, 0, 0);

                  iX := tCR.Right - tCR.Left + 20;

to something like:
Code: [Select]
                    if p.Text <> '' then
                    begin
                      DrawText(b.Canvas.Handle, PChar(p.Text), Length(p.Text), tCR, DT_CALCRECT);
                      iX := tCR.Right - tCR.Left + m_iIconSize + 4;
                    end
                    else
                      iX := m_iIconSize;

I don't like this 4 I think it needs a constant (m_iMargin?). The default height:
Code: [Select]
const
  m_iIconSize      = 16;
  m_iDefaultHeight = 19;
should be even when you use even height for icons, otherwise it will not be centered, maybe:
Code: [Select]
const
  m_iMargin       = 4;
  m_iIconSize      = 16;
  m_iDefaultHeight = m_iIconSize + m_iMargin;

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: language change notification
« Reply #27 on: February 07, 2014, 09:42:14 pm »
You are assuming that m_iIconSize is going to make it out of the clean up process untouched, it will not. It will be replaced with the imagelist (or the attached icon/glyph)  width/height as needed. Making the margin a constant is a good idea though I'll probably end up making it a property so I can decide on a seconds notice that I do not like the default margins. I will post a version of the statusbar unit inside the weekend with your comments implemented as a thank you for your time and then I'm going to postpone development for the time being (again  ::) )
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

 

TinyPortal © 2005-2018