(OS=XP)
・ウィンドウを最前面に移動するとき、SetForegroundWindowだけでは、タスクバーが点滅するだけで終わることがあるので、他ページをみて、下記のようなコードを試しましたが、たまにエラーがでます。ウィンドウは最前面になっているのですが、気になります。どこが間違っているのでしょうか。
エラー
SystemParametersInfo GET OK. LockTimeOut = 17423844
SystemParametersInfo SET(0) Fail. アクセスが拒否されました。
SystemParametersInfo SET(BACK) Fail. アクセスが拒否されました。
コードここから
LockTimeOut: DWORD;
//begin ----------------
if KeyVK = $20 then
begin
Logging('Key = Space');
FormMain.Visible := True;
ForegroundProcessId := GetWindowThreadProcessId(GetForegroundWindow, nil);
CurrentProcessId := GetCurrentThreadId;
if ForegroundProcessId = CurrentProcessId then
begin
Logging('ForegroundProcessId = CurrentProcessId');
if SetForegroundWindow(Application.Handle) then
begin
Logging('SetForegroundWindow OK')
end
else
begin
Logging('SetForegroundWindow Fail')
end;
end
else //if ForegroundProcessId <> CurrentProcessId then
begin
Logging('ForegroundProcessId <> CurrentProcessId');
SetActiveWindow(Application.Handle);
if AttachThreadInput(CurrentProcessId, ForegroundProcessId, True) then
begin
LockTimeOut := 0;
Logging('AttachThreadInput OK');
if not SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @LockTimeOut, SPIF_SENDCHANGE) then
begin
Logging('SystemParametersInfo GET Fail. ' + SysErrorMessage(GetLastError));
end
else
begin
Logging('SystemParametersInfo GET OK. LockTimeOut = ' + IntToStr(LockTimeOut));
end;
if not SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(0), SPIF_SENDCHANGE) then
begin
Logging('SystemParametersInfo SET(0) Fail. ' + SysErrorMessage(GetLastError));
end
else
begin
Logging('SystemParametersInfo SET(0) OK. ');
end;
SetActiveWindow(Application.Handle);
SetForegroundWindow(Application.Handle);
if SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(LockTimeOut), SPIF_SENDCHANGE) then
begin
Logging('SystemParametersInfo SET(BACK) OK. ');
end
else
begin
Logging('SystemParametersInfo SET(BACK) Fail. ' + SysErrorMessage(GetLastError));
end;
AttachThreadInput(CurrentProcessId, ForegroundProcessId, False);
end
else
begin
Logging('AttachThreadInput Fail');
end;
end;
end;
//end ----------------
こんにちは.
よくは分からないのですが,
SystemParametersInfoのSPIF_SENDCHANGEフラグは,トップレベルのウィンのすべてに
WM_SETTIMGCHANGEメッセージを送ります.これは必要ない気がします.
これがエラーの原因かも知れません.
後,気になるのは,Application.Handleですが,そういうこともありますか.
Windows XPということですので,SystemParametersInfoの設定は必要ない気もします.
参考にしたコードが,どのバージョンのOSで動作確認されているかですね.
>参考にしたコードが,どのバージョンのOSで動作確認されているかですね.
でも,タスクバーの点滅はWindows XPからの機能ですね.
う〜む.
Windows XPではSPI_SETFOREGROUNDLOCKTIMEOUTの設定は無効だったような.
>Windows XPではSPI_SETFOREGROUNDLOCKTIMEOUTの設定は無効だったような.
大変失礼しました.動作確認しました.
MSDNオンライン英語版のクラシックスタイルの時に書いてあった気がしたのですが.
勘違いのようです.Windows XP以降のOSでも設定可能ですね.
こんにちは,Mr.XRAYです.
SDKやら調べ,テストしてみました.
以下Windows XP以降の場合です.
SystemParametersInfoのSPI_SETFOREGROUNDLOCKTIMEOUT(SPI_GET...も)アクションは,
デバック(IDEで実行)中は正常動作しない
ただし,[プログラムからデタッチ]すれば正常動作する.これはDelphi2007以降の機能.
フォアグラウンド移行の禁止時間のデフォルト値は非常に大きな値である.つまり,
事実上,SetForegroundWindowに失敗した場合,対応処理をしなければそのウィドウを
自動的にフォアグランドにはできない.
Windows XP以降でタスクバー点滅の機能が導入された.
少なくともWindows XP以降では,今回のコーディングにフォアグラウンド移行の
禁止時間の設定は必要ない.
以上,こんなところです.
いろいろ調べていただいてありがとうございます。
ですが、いまだに、エラーがなぜでるのかわかりません。
下記コードのどこが間違えなのかご指摘いただけるとありがたいです。
ちなみに、このコードで実現したいのは、
ホットキー(今回はスペースキー)を押すことで、
隠れてたウィンドウが最前面にきて、
ユーザーがEDITに何か入力してエンターキーを押すと、
何か処理して隠れる、というようなものです。
main.pas
http://codepad.org/NEpqCl6V
UnitRawInput.pas
http://codepad.org/HTvtk18U
ツイート | ![]() |