This BHO I have works just fine in Win XP IE 8 and Win 7 IE 11 both 32 bit, but not on Win 8.1 64 bit, no EPM.
It retrieves the HWND of an IE 11 window and calls ShowWindow(hwnd, SW_HIDE); on it. The window does not get hidden. Verified with WinSpy that the grabbed window handle is the correct one and the call to the function above returns FALSE with last error = 0.
Help! Thanks
Seems that the BHO dll is loaded into child iexplore processes running at AppContainer or Low Integirty Levels whereas the HWNDs of Internet Explorer all reside in the parent, main iexplore process running at Medium Integrity Level, thus rendering what I was trying to achieve impossible the way I was attempting.
Related
In a Delphi application, when you hover over a border icon, e.g.:
Minimize
Maximize
Restore
it doesn't behave correctly:
Compare to an application that does behave correctly:
Step to Reproduce
Click File, New, VCL Forms Application - Delphi
Click Run (F9)
Hover over the Minimize, Maximize, or Close buttons.
How to fix?
Windows 10, 64-bit (running natively on desktop PC)
Delphi XE6
Edit - It also fails with Delphi 7:
and in Delphi 5:
and in Delphi 4:
I assumed (i.e. was afraid) that it was caused by the ThemeServices engine; where they might have thought it was cool to not honor the user's preferences. But looks like it's something more fundamental.
Compatibility Modes
none: fails
Windows 8: fails
Windows 7: fails
Windows Vista (Service Pack 2): fails
Windows Vista (Service Pack 2): fails
Windows Vista: fails
Windows XP (Service Pack 3) (non-client area theming disabled): works
Windows XP (Service Pack 2) (non-client area theming disabled): works
Windows 98 / Windows Me (non-client area theming disabled): works
Windows 95 (non-client area theming disabled): works
Skype
Also fails in Skype; also written in Delphi:
High DPI is the trigger
I finally figured out why it fails on every Windows 10 machine i've used; but not for everyone. High dpi.
Set your dpi to 97 (101%) or higher.
Close Enough
Dalija's solutions works:
We'll ignore the problem with the tooltip and live to fight another day.
It should also be noted that Windows 10 will suggest that you might have to sign off and sign back on for some applications to work correctly after changing the DPI. This is definitely true of Delphi.
It should also be noted that Delphi doesn't tolerate the DPI changing behind its back like this. This includes adjusting the zoom slider. This would also include placing the app on any monitor besides the primary monitor.
And we never did figure out what the problem is; only kicked it down the road for users running multiple monitors.
QC Bug Report
Because Bor...Impr...CodeG...Embarca... Idera's QC site is behind a pay-wall, here's a copy of the bug report:
http://archive.is/v77rz
As you can see: nobody cares.
High DPI is the trigger and it leads to the solution.
Applications that exhibit the issue are not High DPI aware. Solution to hovering problem is to make them aware or turn on associated compatibility mode by using one of solutions under 1, 2 or 3.
Note: whether will rest of the application behave properly when High DPI awareness is turned on is another issue and will differ from application to application.
Under compatibility mode check "Disable display scaling on high DPI settings"
Call SetProcessDPIAware as first call in .dpr file - as noted by Ian Boyd, calling this function can leat to race condition and preferred way is using manifest. SetProcessDPIAware
Use custom manifest with true or true/PM setting (default Delphi manifest included with "Enable runtime themes" is not high DPI aware)
Current versions of Delphi VCL and FMX frameworks lack support for per monitor DPI awareness, so use true/PM manifest only if you are handling per monitor DPI yourself. Reported to QP as VCL and FireMonkey lack Per-Monitor DPI support for Windows 8.1 (and Windows 10)
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
or
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
Update:
Delphi VCL is source of buggy behavior, specifically issue is somewhere in TForm class or its ancestors. When direct Windows API is used resulting windows behave normally.
Windows API code that behaves properly:
MessageBox(0, 'Correct', 'Caption', MB_OK);
ShowMessage('Correct'); // if themes are enabled -> Windows Task dialog is used
Full Delphi sample app that creates main window without using VCL - behaves properly
program win;
{$R *.res}
uses
Windows,
Messages,
SysUtils;
var
Msg: TMSG;
LWndClass: TWndClass;
hMainHandle: HWND;
function WindowProc(HWND, Msg: Longint; wParam: wParam; lParam: lParam): Longint; stdcall;
begin
if Msg = WM_DESTROY then PostQuitMessage(0);
Result := DefWindowProc(HWND, Msg, wParam, lParam);
end;
begin
LWndClass.hInstance := hInstance;
with LWndClass do
begin
lpszClassName := 'WinApiWnd';
Style := CS_PARENTDC or CS_BYTEALIGNCLIENT;
hIcon := LoadIcon(hInstance, 'MAINICON');
lpfnWndProc := #WindowProc;
hbrBackground := COLOR_BTNFACE + 1;
hCursor := LoadCursor(0, IDC_ARROW);
end;
RegisterClass(LWndClass);
hMainHandle := CreateWindow(LWndClass.lpszClassName, 'Window Title', WS_CAPTION or WS_MINIMIZEBOX or WS_SYSMENU or WS_VISIBLE, 0, 0, 360, 200, 0, 0, hInstance, nil);
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.
Misbehaved VCL forms:
var
f: TForm;
f := CreateMessageDialog('Broken', mtWarning, mbOKCancel, mbOk);
f.ShowModal;
f.Free;
f := TForm.Create(nil);
f.ShowModal;
f.Free;
I was searching on internet how to enable "auto-switch" or "auto-raise" window that has flashing button on taskbar in Windows 7,
and all I can find is how to disable that! I need just opposit, to enable that so i looked at that answers and found registry key
ForegroundLockTimeout. It is set to 200000ms by default i think, so i set it to 1ms, but that doesn't affect anything after Windows XP I guess..
I found that it used to be possible to enable auto switching in Tweak UI from Microsoft, but that doesn't seems to work on Win 7 either.
I tried to program that in Delphi and I can set window on top with SetForegroundWindow, but i can't detect which windows need attention - are flashing.
It is even possible to detect foreground window with GetForegroundWindow, but not window that is flashing so i could set it on top.
So my question is, is it possible in delphi to get hwnd of that window that needs focus in background?
I have two different applications, both native applications written in C++Builder 2009, both MDI, and both using the same progress bar utility code. One of them properly updates the Windows 7 taskbar with its progress. The other one doesn't.
I can't find any obvious differences between the two applications. No errors are reported in the failing application: the calls to ITaskbarList3::SetProgressValue and ITaskbarList3::SetProgressState return S_OK, but nothing happens in the Windows 7 taskbar.
Are there any gotchas in getting the Windows 7 taskbar progress bar to work? Any requirements that I might be missing?
My problem was likely specific to Delphi/C++Builder and was the result of a difference in how the VCL handles its top-level window.
If Application.MainFormOnTaskBar is true, then ITaskbarList3 only works if Application.MainFormHandle is used as the HWND parameter.
If Application.MainFormOnTaskBar is false, then ITaskbarList3 only works if Application.Handle is used as the HWND parameter.
In my case, one project had MainFormOnTaskBar true, and one had it false.
I have not written an app using the Windows 7 progress bar specifically but I have written many .Net apps that require updating progress using a live animation and the biggest gotcha from my experience was being sure you were updating the progress bar on the main thread.
I am trying to write a program that gets the windows that are displayed on the screen. Something like screen.getActiveWindow().size would be cool, but it only addresses the active window.
I am looking for the sizes of all windows on the screen, as well as event information when they are resized, cover each other up.
Am I just daydreaming or is there a way to get this information on windows?
You need to use EnumWindow Function go get the hwnd of each window then user EnumChildWindow to get the child windows and finally get windowinfo the clr doesn't have all of the necessary function to do low level window manipulation unless its been added in 4.0 and I haven't noticed.
I have an application that manages patient demographic information. Along with this data a user can scan a picture of a patient and assign that picture to a patient. When the user clicks the scan button a separate application is opened as a dialog in order to scan the image. When running this on XP everything worked fine. The imaging application loaded up fine and gained focus. On Vista however occasionally the imaging application will not gain focus and will popup behind the main application. When running full screen or through 2008 Application Server you cannot see the application, you only get a locked screen and it appears nothing has happened. Is there any way to change the window focus management on Vista to work the way XP did? I'm looking for a way to solve this without making changes to the actual application if possible.
I think you will have to make changes to your application to allow the imaging application to take the focus. I'm going to assume that your application launches the imaging application through ShellExecute or CreateProcess. If so, you can get the process handle of the launched process either through SHELLEXECUTEINFO.hProcess (for ShellExecute) or PROCESS_INFORMATION.hProcess (for CreateProcess). Immediately after launching the imaging application call the AllowSetForegroundWindow API:
AllowSetForegroundWindow(GetProcessId(hProcess));
This will allow the imaging application to place its main window/dialog in the foreground when it's starting up.
You could try the following steps:
1. Right Click on the exe
2. Select Properties
3. Select the Compatibility Tab
4. Check the Run this program in campatibility mode for:
5. Select Windows XP (Service Pack 2)
You could iterate through all top level HWNDs and identify the scanning application via its window class, then send an appropriate message to raise the window.
I don't believe this is Vista vs XP related. I think that simply this imaging app takes longer to start on Vista.
Since Windows 2000, the window manager has prevented background applications stealing the foreground. When an application is launched, it has a window of opportunity to create and show a window that will take the foreground. If it takes too long, the window manager thinks that the current window should keep the foreground, and inhibits the other app taking the foreground when it does finally launch.
I can't think of any specific way to avoid this... other than using FindWindow to search for the other apps window after launching the app. When you eventually find it, call SetForegroundWindow on it to bring it to the foreground.