0

I need to detect whether a specific window is minimized or not. For this purpose I have found two functions:

1.

function PAIsWindowMinimized(h: HWND): Boolean;
// Detects whether a window is minimized or not
var
  wp: Winapi.Windows.WINDOWPLACEMENT;
begin
  wp.length := SizeOf(Winapi.Windows.WINDOWPLACEMENT);
  Winapi.Windows.GetWindowPlacement(h, @wp);
  Result := wp.showCmd = Winapi.Windows.SW_SHOWMINIMIZED;  
end;

2.

// Alternative (https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isiconic):
Winapi.Windows.IsIconic(h);

Which of the two alternatives is preferable? Or are they equally good in all situations?

user1580348
  • 5,721
  • 4
  • 43
  • 105
  • 3
    What about third method: GetWindowLong(hwnd, GWL_STYLE) & WS_MINIMIZE ? – user2120666 Jul 09 '19 at 13:59
  • 2
    IsIconic is of course better because of its brevity. This is why this question is opinion based, someone else might have a different perspective.. In general, any **best** question is opinion based. – Sertac Akyuz Jul 09 '19 at 14:16
  • 2
    I'm afraid that this is the canonical "opinion based" question. Perhaps what you meant to ask was, "is there any semantic difference between these two functions". – David Heffernan Jul 09 '19 at 14:26
  • 3
    @IInspectable: Are you sure? Or confused with WS_MINIMIZEBOX ? – user2120666 Jul 09 '19 at 14:42
  • @use: Indeed I had `WS_MINIMIZE` confused with `WS_MINIMIZEBOX`. – IInspectable Jul 09 '19 at 18:54
  • This question is opinion based, that is why i voted to close it (i did not downvoted, closing is enough IMHO) I guess the down vote is for the same reason – GuidoG Jul 10 '19 at 08:05
  • IMO this question is not opinion based after all, since the answer by @Remy is correct and *conclusive*. it could have been rephrased better e.g. "what is the proper way to check if a window is minimized"... – kobik Jul 10 '19 at 09:11
  • @kobik So edit the question to make it not opinion based, preferably with the wording from my comment rather than yours, which still has an slight air of opinion. A question can't be shown not to be opinion based by an answer being factually correct. A question that asks, which method is preferable is by definition opinion based. A simple edit to the question is all it takes. Doesn't matter who does it. If you feel strongly that this question has value, invest the time to make the edit. Asker had the chance to do so but chose not to. – David Heffernan Jul 10 '19 at 10:26
  • @kobik - Remy's answer is his opinion, it's not correct or incorrect. E.g. ws_minimize is a documented flag, it can't be a hack to query or set it regardless of there being a function to set it. – Sertac Akyuz Jul 10 '19 at 10:41
  • @SertacAkyuz, You got a point there about the "hack" wording. however your comment is also pretty conclusive about using `IsIconic`. in any case I'll let the OP edit his question if he wishes. – kobik Jul 10 '19 at 10:49
  • @kobik - Heh, it's just my opinion, I wouldn't post it as an answer. :) – Sertac Akyuz Jul 10 '19 at 10:54
  • @ser: The `WS_MINIMIZE` flag is [documented](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-styles). That documentation does not provide any guarantees about the flag being updated after a window has been created. Checking for a flag outside its documented specification is relying on implementation details. That's commonly called a *"hack"*. – IInspectable Jul 10 '19 at 13:53
  • @IIns - I have no idea what you mean by *".. documentation does not provide any guarantees about the flag being updated after a window has been created"*. You either set the flag or not depending on if you want to create a minimized window or not while you're calling CreateWindowEx. There's nothing not documented about it. Querying a documented flag is not a hack, that's not even an opinion but a fact. – Sertac Akyuz Jul 10 '19 at 14:04
  • @ser: I provided a link to the documentation so I didn't have to read it for you. That didn't work out, so here it is: *"`WS_MINIMIZE`: The window is initially minimized. Same as the `WS_ICONIC` style."* Take special note, that the documentation doesn't say what you read into it, namely: *"The window is minimized."* Since it doesn't, that aspect is undocumented, and testing for that flag at any time is relying on implementation details. – IInspectable Jul 10 '19 at 14:14
  • @Iins - Sorry but documentation is not a one liner you happen to find through a simple search. Winapi is vast, you have to have some insight and experience to make out what is available and what is not. That will happen in time. Meanwhile I will refer to you to the documentation of GetWindowLong, it states that you can retrieve window styles, it doesn't state that you can't retrieve WS_MINIMIZE. – Sertac Akyuz Jul 10 '19 at 14:23
  • @ser: So... where's the documentation, then, that provides the guarantees you purport? If you cannot find it, then by definition, it is undocumented. And no, there is no such thing as implied guarantees, as I take your *"everything that's not explicitly denied is true"* to mean. As for your `GetWindowLongPtr` failure-of-proof: Sure, it allows you to discover window styles, all of them even. It does not, however, provide any guarantees as to whether or not the `WS_MINIMIZE` style ever gets updated during the life of a window, to reflect its current state. – IInspectable Jul 10 '19 at 14:35
  • 2
    @Iins - The definition of a minimized window is one that has the WS_MINIMIZE flag. Read that on MS [documentation](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-features#minimized-maximized-and-restored-windows). Thus, a window without the flag is not minimized. Evidently I will not be able to provide you with any guidance through reading documentation, or anything else for that matter. So good luck to you in learning Winapi. – Sertac Akyuz Jul 10 '19 at 14:45
  • @ser: That's not documentation. That's non-normative information. Rest assured, that if someone has earned a winapi gold badge, they sometimes aren't wrong. Good luck getting there. – IInspectable Jul 10 '19 at 14:53
  • @ser: Normative documentation resides under sections titled *"reference"*, e.g. [Window Reference](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-reference). Everything else is non-normative, non-binding, non-contractual. It attempts to be accurate, but there is no contract, legal or otherwise, that it is. – IInspectable Jul 10 '19 at 15:27

2 Answers2

10

IsIconic() is the proper and documented way to check if a window is minimized:

IsIconic function

Determines whether the specified window is minimized (iconic).

Window Features

The IsZoomed and IsIconic functions determine whether a given window is maximized or minimized, respectively. The GetWindowPlacement function retrieves the minimized, maximized, and restored positions for the window, and also determines the window's show state.

Using anything else is a hack at best. The fact that IsIconic() and GetWindowPlacement() internally check the HWND for the WS_MINIMIZE window style is just an implementation detail. The overhead of using these functions rather than checking the window style manually is negligible.

Stick with IsIconic(), it is the API that Microsoft specifically provides for this exact purpose.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
-2

The 'best' alternative is calling (GetWindowLong(hwnd, GWL_STYLE) & WS_MINIMIZE).

I checked IsIconic and GetWindowPlacement functions in dissassembler and both internally compares windows styles with WS_MINIMIZE flag to determine if window is minimized.

user2120666
  • 579
  • 1
  • 4
  • 16
  • When writing this I get a lot of compiler errors. – user1580348 Jul 09 '19 at 15:55
  • Modify it to become a boolean pascal expression. But IMO the answer is not correct anyway, unless you're checking hundreds of windows in a loop... – Sertac Akyuz Jul 09 '19 at 16:25
  • @SertacAkyuz How would you transform it to a pascal expression? And why do you think the answer is not correct anyway? – user1580348 Jul 09 '19 at 16:34
  • @SertacAkyuz How would you transform it to a Boolean expression? And why do you think the answer is not correct anyway? – user1580348 Jul 09 '19 at 16:40
  • 2
    `GetWindowLong(hwnd, GWL_STYLE) and WS_MINIMIZE = WS_MINIMIZE` I already explained my view on the other question. – Sertac Akyuz Jul 09 '19 at 16:55
  • 3
    This is not Pascal. In Pascal, the bitwise and operator is not `&`, but `and`. Also, an integer will not be automatically converted into a boolean. Sertac has given the correct Pascal version (although I personally prefer `<> 0`). – Andreas Rejbrand Jul 09 '19 at 22:05