I would like change the keyboard layout of Windows PE without restarting the
system (I think using ActivateKeyboardLayout changes only the keyboard
layout of the current application, but I want to change it for all
applications).
Is there a possibility to do this with a script (e.g. changing the entries
in the registry and restarting a service using devcon)?
Thanks for your tips,
Boris
--
MichKa [MS]
This posting is provided "AS IS" with
no warranties, and confers no rights.
"Boris Mebarek" <BorisM...@hotmail.com> wrote in message
news:ORsgSIXd...@TK2MSFTNGP11.phx.gbl...
thank your for the answer.
I tried it with a delphi programm, but it didn´t work.
Here is the code:
procedure TPEConfigForm.Button1Click(Sender: TObject);
var Tastatur_HKL: HKL;
LW, HW: Word;
begin
if not SystemParametersInfo(SPI_GETDEFAULTINPUTLANG, 0, @Tastatur_HKL,
SPIF_SENDCHANGE)
then Application.MessageBox(PChar('No query possible'), 'ERROR', 0);
LW := StrToInt('$' + '00000409'); {HexCode für US-Tastatur, als Integer
1033}
HW := HiWord(Tastatur_HKL);
Tastatur_HKL := MakeLong(LW, HW);
if not SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, @Tastatur_HKL,
SPIF_UPDATEINIFILE or SPIF_SENDCHANGE)
then Application.MessageBox(PChar('No changes possible'), 'ERROR', 0);
end;
GETDEFAULTINPUTLANG works, the LoWord and the HiWord (?) of Tastatur_HKL are
1031 (=0x407, german keyboardlayout).
When trying SPI_SETDEFAULTINPUTLANG I get the error 'No changes possible'.
Any ideas?
Boris
"Michael (michka) Kaplan [MS]" <mic...@online.microsoft.com> schrieb im
Newsbeitrag news:uM8F0MXd...@TK2MSFTNGP09.phx.gbl...
You may want to look at the following KB article for loading a layout:
http://support.microsoft.com/?scid=kb;en-us;289125
--
MichKa [MS]
This posting is provided "AS IS" with
no warranties, and confers no rights.
"Boris Mebarek" <borism...@hotmail.com> wrote in message
news:OiV6%23jgdD...@tk2msftngp13.phx.gbl...
sorry, but I think I don´t really understand.
I have now loaded first the new keyboard layout (german), and it is
activated and works in my application.
Afterwards I run SystemParametersInfo with SPI_SETDEFAULTINPUTLANG and a
pointer to the keyboardlayout (=@Tastatur_HKL) I loaded, but now I get an
error nr. 0 and the keyboard layout in other applications is still the us
layout (409).
Here is my source code:
procedure TPEConfigForm.Button1Click(Sender: TObject);
var Tastatur_HKL: HKL;
FehlerCode: Word;
begin
Tastatur_HKL := LoadKeyboardLayout('00000407', KLF_ACTIVATE); //
Keyboardlayout loaded, the current layout in my application is now german
if not SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, @Tastatur_HKL,
SPIF_UPDATEINIFILE or SPIF_SENDCHANGE) then
begin
FehlerCode := GetLastError;
Application.MessageBox(PChar(IntToStr(FehlerCode)), 'ERROR', 0); //
Now I get the errorcode 0
end;
end;
Could You give me an example how to do it right?
Greetings,
Boris
"Michael (michka) Kaplan [MS]" <mic...@online.microsoft.com> schrieb im
Newsbeitrag news:u4UONGid...@TK2MSFTNGP10.phx.gbl...
> sorry, but I think I don´t really understand.
You are mixing up *three* things here -- KLIDs (keyboard layout IDs), HKLs,
and LANGIDs.
Do not pass the HKL to the SystemParametersInfo API; instead just pass the
lang. I know that the docs claim they want an HKL but I have had real
problems trying to pass anything beyond the language (though sometimes I was
able to make a numeric KLID work).
Note that this does not change running applications even when it does work;
it changes new processes only.
SPI_SETDEFAULTINPUTLANG:
Sets the default input language for the system shell and applications. The
specified language must be displayable using the current system character
set. The uiParam parameter is not used. The pvParam parameter must point to
a 32-bit variable that contains the keyboard layout handle for the default
language.
Sets the default input language for the system shell and applications. The
specified language must be displayable using the current system character
set. The pvParam parameter must point to an HKL variable that contains the
input locale identifier for the default language. For more information, see
Languages, Locales, and Keyboard Layouts.
Is it wrong to pass the handle of a loaded keyboard layout to the
SystemParametersInfo API?
The language ID for Germany is 0x0407, I have tried to pass a 16-bit
variable (0x0407 = 1031), but it didn´t work.
What do I have to pass instead?
Boris
"Michael (michka) Kaplan [MS]" <mic...@online.microsoft.com> schrieb im
Newsbeitrag news:##NMWBjdD...@TK2MSFTNGP12.phx.gbl...
To get back to your original question, there really is no other way short of
a global hook that changes the layout in every thread of every process
(which is definitely overkill). The true intent of this setting is for it to
be a user choice, though.
--
MichKa [MS]
This posting is provided "AS IS" with
no warranties, and confers no rights.
"Boris Mebarek" <borism...@hotmail.com> wrote in message
news:efNTI8pd...@TK2MSFTNGP09.phx.gbl...
finally it works!!!
var KeyboardHandle: HKL
KeyboardHandle := LoadKeyboardLayout('00000407', KLF_ACTIVATE) //get
handle and load german keyboard
SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, @KeyboardHandle,
SPIF_SENDCHANGE) //pass the handle to SystemParametersInfo
That´s all.
The last error I made was to combine "SPIF_UPDATEINIFILE or
SPIF_SENDCHANGE".
Thank you, Michael, for your patience.
Boris
"Michael (michka) Kaplan [MS]" <mic...@online.microsoft.com> schrieb im
Newsbeitrag news:OzcdX3qd...@TK2MSFTNGP11.phx.gbl...
--
MichKa [MS]
This posting is provided "AS IS" with
no warranties, and confers no rights.
"Boris Mebarek" <borism...@hotmail.com> wrote in message
news:OrYAe4rd...@TK2MSFTNGP11.phx.gbl...
"Michael \(michka\) Kaplan [MS]" <mic...@online.microsoft.com> wrote in
news:##NMWBjdD...@TK2MSFTNGP12.phx.gbl:
> You are mixing up *three* things here -- KLIDs (keyboard layout IDs),
> HKLs, and LANGIDs.
>
> Do not pass the HKL to the SystemParametersInfo API; instead just
> pass the
> lang. I know that the docs claim they want an HKL but I have had real
> problems trying to pass anything beyond the language (though sometimes
> I was able to make a numeric KLID work).
I'm getting in this kinda late since I've only been experiencing issues
about this today. The first remark I have is: the doc claims it wants an
HKL, and when I do pass an HKL (obtained from LoadKeyboardLayout), it does
work. However, the layouts I've been testing have no high-word data
(namely, 00000409 and 0000040c, resp. en_US and fr_FR).
I'm nonplussed by your assertion that a 32-bit value with only a zero'd
higher word is required. Is this documented anywhere (KB, etc.)?
> Note that this does not change running applications even when it does
> work; it changes new processes only.
I concur, but what's weird is: apparently Boris managed it, if you look at
the end of the thread I just forked (article #13706). How did he do it? I
noticed he doesn't use the much-encouraged flags such as
KLF_SUBSTITUTE_OK, which I do. Maybe that's why it doesn't change my
current apps' keyboard, but that's just fine with me anyway.
Finally, my REAL ISSUE here: my code works just fine when run from a
standalone app, launched by the current user (it gets an HKL, calls
SystemParametersInfo with SPIF_SENDCHANGE as a last argument). When run,
it does change my app's layout (which I don't really care about) *and* the
default settings, as exhibited by the Input Settings dialog accessible
from the language bar, for instance.
HOWEVER, when run from a service app, which runs as LocalSystem, it
doesn't have any impact. I've spent some time delving into the API and
couldn't seem to find how to manage this.
The goal is simple: I maintain this service-based remote administration
agent, which can do a large amount of tasks... The latest addition we wish
to make is remote changing of the default keyboard layout. That's because
some of our workstations use fr_FR keyboards while others use en_US. When
we deploy a full new dump of the Windows partition, it comes with a single
keyboard setting (while some SysPrep tweaking could change that), and we
wish to be able to remotely update default input locale for masses of
computers at a time once they're up and running.
Any idea?
--
Christophe Porteneuve a.k.a. TDD
Email: chris...@magix-team.org
* Please do not include original text unnecessarily *
> I'm getting in this kinda late since I've only been experiencing issues
> about this today. The first remark I have is: the doc claims it wants an
> HKL, and when I do pass an HKL (obtained from LoadKeyboardLayout), it does
> work. However, the layouts I've been testing have no high-word data
> (namely, 00000409 and 0000040c, resp. en_US and fr_FR).
Those are Keyboard Layout Identifiers (KLIDs), as I said previously. KLIDs
are not HKLs.
> I'm nonplussed by your assertion that a 32-bit value with only a zero'd
> higher word is required. Is this documented anywhere (KB, etc.)?
I did not say that they are 32-bit values with zero'd higher words. Try it!
> > Note that this does not change running applications even when it does
> > work; it changes new processes only.
>
> I concur, but what's weird is: apparently Boris managed it, if you look at
> the end of the thread I just forked (article #13706). How did he do it? I
> noticed he doesn't use the much-encouraged flags such as
> KLF_SUBSTITUTE_OK, which I do. Maybe that's why it doesn't change my
> current apps' keyboard, but that's just fine with me anyway.
>
> Finally, my REAL ISSUE here: my code works just fine when run from a
> standalone app, launched by the current user (it gets an HKL, calls
> SystemParametersInfo with SPIF_SENDCHANGE as a last argument). When run,
> it does change my app's layout (which I don't really care about) *and* the
> default settings, as exhibited by the Input Settings dialog accessible
> from the language bar, for instance.
Well, note that it is easy to update the process you are in. Its updating
processes other than the one you are in that cannot happen.
> HOWEVER, when run from a service app, which runs as LocalSystem, it
> doesn't have any impact. I've spent some time delving into the API and
> couldn't seem to find how to manage this.
Entirely by design. These are PER-USER settings. You cannot run as another
user and expect it to change for you....
> The goal is simple: I maintain this service-based remote administration
> agent, which can do a large amount of tasks... The latest addition we wish
> to make is remote changing of the default keyboard layout. That's because
> some of our workstations use fr_FR keyboards while others use en_US. When
> we deploy a full new dump of the Windows partition, it comes with a single
> keyboard setting (while some SysPrep tweaking could change that), and we
> wish to be able to remotely update default input locale for masses of
> computers at a time once they're up and running.
Well, see above. You cannot change user settings unless running as the user
in question.
>
> Any idea?
Why not try an EXE that you "RunAs" someone else?
--
MichKa [MS]
NLS Collation/Locale/Keyboard Development
Globalization Infrastructure and Font Technologies
> Those are Keyboard Layout Identifiers (KLIDs), as I said previously.
> KLIDs are not HKLs.
Ooops. I meant those KLIDs were what I used for LoadKeyboardLayout, while
this latter function's resulting HKL was what I pointed on for
SystemParametersInfo.
> Well, note that it is easy to update the process you are in. Its
> updating processes other than the one you are in that cannot happen.
Yeah, which is not really the issue for me at any rate. The
SPI_SETDEFAULTINPUTLANG command updates default layout for upcoming
processes, right? However, this is per-user, which is understandable.
So I wonder what would be an appropriate solution for my issue here. We're
a small IT college with several PC labs for our students. Some of those
labs are equipped with US keyboards, some with FR ones (some even mix
them). Our students can log in on any box, since it's domain-based and
they have a roaming profile. I'm looking for a way to change their
keyboard input setting when they log in to the machine's physical keyboard
configuration.
Maybe some software in HKLM\Software\Microsoft\Windows\Run looking up the
physical config will do the trick. My service would just update this
information in a private registry key. What do you think?
> Ooops. I meant those KLIDs were what I used for LoadKeyboardLayout, while
> this latter function's resulting HKL was what I pointed on for
> SystemParametersInfo.
I think you will find that this does not work as you expect.
> > Well, note that it is easy to update the process you are in. Its
> > updating processes other than the one you are in that cannot happen.
>
> Yeah, which is not really the issue for me at any rate. The
> SPI_SETDEFAULTINPUTLANG command updates default layout for upcoming
> processes, right? However, this is per-user, which is understandable.
Yep.
> So I wonder what would be an appropriate solution for my issue here. We're
> a small IT college with several PC labs for our students. Some of those
> labs are equipped with US keyboards, some with FR ones (some even mix
> them). Our students can log in on any box, since it's domain-based and
> they have a roaming profile. I'm looking for a way to change their
> keyboard input setting when they log in to the machine's physical keyboard
> configuration.
Well, the truth is that they can have any keyboard they like. How about just
letting them choose the one they want and using it? There is no way to
determine what the installed keyboard type is.
> Maybe some software in HKLM\Software\Microsoft\Windows\Run looking up the
> physical config will do the trick. My service would just update this
> information in a private registry key. What do you think?
I don't think you have a way to retrieve that info. I think the solution is
overkill -- why not just give them two shortcuts to click on, to let them
choose which keyboard they want?
> I don't think you have a way to retrieve that info. I think the
> solution is overkill -- why not just give them two shortcuts to click
> on, to let them choose which keyboard they want?
As for the info: we do have it outside the system, so we can force it on
the services through the network (which is the whole point).
As for the big picture, I agree, this may be overkill. Plus, setting the
default input locale from the service won't change the active input locale
in the login screen they get once they Ctrl+Alt+Del, will it?
Also, even so, I suppose once they do log in their own keyboard layout
will kick in, cancelling what we put in.
So a user who last worked on a FR-keyboard workstation and then logs on a
US-keyboard one will have to redefine the keyboard, won't they? Too bad...
At least, I wish we could remotely update the login dialog default input
locale so they don't have to click Options... and change it with Alt+Shift
if need be.