I'm looking for confirmation on this windows programming idiom, am I correct in thinking that many different types of "handles" are passed around as not only LRESULT objects but also lParam and wParam objects?
I'm guessing that as long as we know "what" type of handle is in LRESULT or lParam/wParam we can cast back into it.
For example
case WM_CREATE:
...
//create a window
//lParam is the CREATESTRUCT for new window created here
....
return lParam;
...
...
CREATESTRUCT cStruct = (CREATESTRUCT)SendMessage(hwnd, msg /*WM_CREATE*/);
cStrcut.cx;//this is the width of the new window?
correct?
Is this is "correct"? Can anyone provide me and the StaticOverflow community a short thesis on this technique/idiom?
Questions:
Should we only return lParam (or only wParam) values?
Are there any pitfalls one should know about?
Both LRESULT and LPARAM are LONG_PTR types, which are 32 or 64 bit integers. I'm not a seasoned C programmer, but it appears these integers are just being used as "buffers" which the programmer later casts into their "real" type before using... sound accurate?
This style of programming is "bad" as there is no way to know what something really is at compile-time. That said, as the WIN32 API is a C API (instead of say, C++), there's not much else that can be done when one wants to pass around any type of struct using the same method signature.
So, the API design team decided to have two parameters to handle this. A 32-bit LPARAM and a 16-bit WPARAM.
When working with the Win32 C API, you're just going to have to make sure you read the documentation correctly and ensure you're casting to the right thing that the documentation says it is.
So to answer your question, you are correct - but only because you have no other choice. In an attempt to be complete here, MFC came along (for C++ programmers), but that isn't considered a good object-orientated library - it's more of a wrapper. There are others out there that do a much better job (e.g. wxWidgets).
Related
Is this a memory address ranging to (theorically) 2^32-1 on 32-bit machine?
The reason I'd like to know that is I'm trying to somehow associate a HWND returned by CreateWindow() to a class instance, so in order to know how properly store that HWND value, I need to know what's the values like, so I can see what can fit better, AA array, linked list with hash table, etc.
From the documentation for MFC (to avoid confusion: this is documentation where CWnd and "window object" in the article is a C++ class in your program, not USER32):
The Windows window, on the other hand, is an opaque handle to an internal Windows data structure that corresponds to a window and consumes system resources when present.
Opaque handles must be treated as "black boxes" or atomic blobs that must not be altered and likely won't reveal any useful information through introspection either.
Also, see Wikipedia: https://en.wikipedia.org/wiki/Handle_(computing)
To store a value you need to know its type only. As documented under Windows Data Types, an HWND is a type alias for a HANDLE, which is a type alias for PVOID, which in turn is a type alias for void*.
In other words: An HWND is a pointer to unknown data. It's pointer-sized and trivially copy-able.
I am learning the winAPI through the docs and I am kind of puzzled by this one thing. The docs use CALLBACK and WINAPI in the same example and when I tried peeking their definition, they were both defined as __stdcall. If both are defined as the same thing, what's the point of having two different definitions for just __stdcall?
Also worth noting that while peeking their definitions I also found APIPRIVATE and PASCAL which were defined as __stdcall. What's the point? Can I just replace every instance of those 4 definitions with __stdcall or is it problematic?
WINAPI is the decoration used for APIs that Windows exposes to you.
CALLBACK is the decoration used for callback functions that you pass to Windows.
Replacing them with __stdcall is problematic only insomuch as your code might ever be deemed good enough for other developers to use, who might try and use a gcc, llvm or other compiler that can target Windows, but does not support __stdcall as a keyword (except probably does as a backwards compatibility hack because of the number of times reasoning such as the above went unchallenged).
This is Line 519 of WinNT.h (BUILD Version: 0091)
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
Why do we need a pointer to an struct with a single int member with a weird name called unused?
And will we ever need to use a line of code like this one?
HINSTANCE hInstance = new HINSTANCE__;
Overall declaring different data types with the same structures, doesn't make sense to me. What's the idea behind this?
DECLARE_HANDLE(HRGN);
DECLARE_HANDLE(HRSRC);
DECLARE_HANDLE(HSPRITE);
DECLARE_HANDLE(HLSURF);
DECLARE_HANDLE(HSTR);
DECLARE_HANDLE(HTASK);
DECLARE_HANDLE(HWINSTA);
DECLARE_HANDLE(HKL);
The point is for the different handles to have different types so that, for example, a HINSTANCE isn't assignable to a HANDLE. If they were all defined as "void*", then there are classes of errors that the compiler could not detect.
And will we ever need to use a line of code like this one?
HINSTANCE hInstance = new HINSTANCE__;
You usually use a HINSTANCE value returned by a Windows system call; I have never seen code executing a line like that.
They don't actually point to anything to memory; they are just used to refer to objects (files, resource, semaphores, windows) when making calls to the Windows API. While they're nothing more than just indexes into kernel's object tables, the developers decided that they make it a pointer to an unused structure which would make them "opaque" and cause less confusion between other types. The DECLARE_HANDLE is a function macro that does just that - declaring opaque types for handles.
The HINSTANCE of a win32 application is passed to WinMain, but is there any other way of determining the current HINSTANCE (in case you couldn't tell, I'm very new to win32 programming!)? I need to create a window inside of a library and (since the library is cross platform), id prefer not to have to pass it in.
If memory serves, GetModuleHandle(NULL); returns the instance handle.
__ImageBase is your friend, especially in the case of libraries.
Note that the linked blog post (by R. Chen, although not the same post as the one linked by Brian Bondy) is worth reading (including the comments!)
If you are using MFC, you can use AfxGetInstanceHandle.
If you are not using MFC you can use: GetWindowLong(hWnd, GWL_HINSTANCE)
The function AfxGetStaticModuleState() does the trick.
If you call it within a dll, the functions returns the handle to the dll, if the call within a exe it returns the handle to the executable.
DWORD size;
TCHAR fileName [MAX_PATH];
HMODULE hModule = AfxGetStaticModuleState()->m_hCurrentInstanceHandle;
::GetModuleFileName (hModule, fileName, size);
Does anyone know what parameters to pass to dwmapi.dll ordinal #113? (Windows 7)
I'm trying to incorporate this method into an application that I'm writing. From what I can tell, this method is responsible for doing the Aero peek thing for windows. If I pass no params to the method it will show the desktop and outlines of all open, non-maximized windows. Nothing happens when I try passing parameters - which I've done using trial and error.. mostly error.
Any help would be greatly appreciated.
Don't do it. It's undocumented for a reason and is subject to change and/or removal at any time. Given that Windows 7 hasn't been release yet you won't even be able to guarantee that it'll be there in the final version.
Your tags are inconsistent. An API is an application programming interface. Ordinal #113 is undocumented because it's not part of the interfaces for applications. It is likely present because the OS needs it itself, or because the current RC hasn't finished removing it, etc.
Well, I've used to mimic Alt-Tab with AeroPeek feature.
using System.Runtime.InteropServices;
...
[DllImport("dwmapi.dll", EntryPoint = "#113", SetLastError = true)]
internal static extern uint DwmpActivateLivePreview(uint a, IntPtr b, uint c, uint d);
...
//To call it
IntPtr peekHwnd = //<-- here goes the application Handle to aeropeek
//to enable
DwmpActivateLivePreview(1, peekHwnd, 0, 1);
...
//to disable
DwmpActivateLivePreview(0, peekHwnd, 0, 1);
Use it carefully, since many comments tell you that it is undocumented for some reason.
I think is because aeropeek is not supported by all windows editions, home basic is not supported, maybe you can implement your own window peek or at least fake it using alpha transparency (while drawing some border) and querying for underlying windows using the window rectangle coordinates like the rectangle collision detection algorithm.
Please go read Raymond Chen's blog until you realize this is a really, really, really bad idea!
There's a reason that apps can't activate Aero Peek - the user gets to choose when that happens, not you.