Sind HWND immer unique?
-
Stimmt das noch? Auf Windows 95 kann ich mich erinnern dass es ein 65K Limit gab und damit hatten wir massiv Probleme. Seit XP hatte ich keine solchen Probleme mehr. Daher hätte ich angenommen dass es dieses 65K Limit eben nicht mehr gibt, und dann kann der verlinkte Artikel nicht mehr aktuell sein.
Daran dass ein HWND kein Pointer ist wird sich aber vermutlich nichts geändert haben.
-
-
hustbaer schrieb:
Daran dass ein HWND kein Pointer ist wird sich aber vermutlich nichts geändert haben.
ntdef.h definiert Handles so:
typedef void *HANDLE;
in windef.h finden wir:
DECLARE_HANDLE (HWND);
und bezüglich DECLARE_HANDLE (in ntdef.h)
#ifdef STRICT typedef void *HANDLE; #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name #else typedef PVOID HANDLE; #define DECLARE_HANDLE(name) typedef HANDLE name #endif
-
WinFreak not Winfried schrieb:
...
Ja und?
-
dot schrieb:
Ich kann da nix zum Thema Window-Handles finden, und Kernel Handles sind gänzlich andere Tiere.
EDIT: Doch, da steht's: https://blogs.technet.microsoft.com/markrussinovich/2010/02/24/pushing-the-limits-of-windows-user-and-gdi-objects-part-1/
Sind wohl immer noch max. 64K USER Handles und davon max. 32K Fenster. Hm. Dann muss das Limit auf Win95 entweder noch niedriger gewesen sein oder ... irgendwas anderes
Auf Win95 war bei 3-4 Visual Studio 6 Instanzen auf jeden Fall schluss, da haben dann schon Buttons gefehlt in vielen Dialogen. Auf XP war das nie ein Thema. Egal /EDIT@WinFreak not Winfried
Ja, ich kenne die Header-Files.Es ist formal ein Zeiger. Aber ein gültiger HWND Wert zeigt nicht auf irgend ein gültiges Objekt (ausser durch Zufall). Weil es eben nicht wirklich ein Zeiger ist. In Wirklichkeit sind es mehrere verschiedene Integerwerte die in einen 32 Bit Integer zusammengepackt werden und dann zu einem Zeiger gecastet.
Einer dieser Integerwerte ist ein Index in einen Table in dem dann der wirkliche Zeiger auf das Objekt vermerkt ist.Und ganz nebenbei ist das die Definition von HANDLE und nicht die von HWND. HANDLE != HWND. Komplett andere Baustelle. KERNEL vs. USER. Ändert aber nix wesentliches, beides sind Handles und keine echten Zeiger, auch wenn sie als Zeiger getarnt daherkommen.
Langer Rede kurzer Sinn: Die Aussage "HWNDs sind Pointer auf eine Struktur" ist nicht richtig. HWNDs sind zwar formal Zeiger, aber sie zeigen eben nicht auf eine Struktur.
-
hustbaer schrieb:
Und ganz nebenbei ist das die Definition von HANDLE und nicht die von HWND.
Man beachte:
typedef void *HANDLE;
und:
#define DECLARE_HANDLE(name) typedef HANDLE name
sowie:
DECLARE_HANDLE (HWND);Alles in allem: HWND ist ein void*
Einen Pointer nicht als Pointer zu benutzen ist recht unsinnig.
Vermutlich werden HWNDs in Listen verwaltet und etwa so erzeugt: HWND hwnd = malloc (sizeof(WND)).Mal die CreateWindow-Funktion untersuchen. Ich habe die geleakten Sources von NT4. Werde nachher mal nachschauen.
-
WinFreak not Winfried schrieb:
ntdef.h definiert Handles so:
typedef void *HANDLE;
...
Und genau das ist kein Beweis! Das ist nur ein Trick damit die unterschiedlichen HANDLES intern nicht vertauscht werden können.
Ein nette Sache der API Entwickler.In der Win16 API kam das erst mit der Einführung von Win16-STRICT. (Meine Güte ist das lange her <seufz />... und ja, damals habe ich auch schon programmiert )
Damit hatte man endlich Fehlermeldungen wenn man ein HWND mit einem GDI-Handle verwechselte...
Was intern für casts passieren weißt Du nicht. Theoretisch könnte ein HWND ein Pointer oder zumindest Pointer offset sein...
-
Hier ist die CreateWindow-Funktion
https://github.com/killbug2004/NT_4.0_SourceCode/blob/master/nt4/private/ntos/w32/ntuser/kernel/createw.cDas HWND ist intern ein PWND.
Die Zeile 165 sieht so aus:pwnd = HMAllocObject(ptiCurrent, pdesk, TYPE_WINDOW, sizeof(WND) + pcls->cbwndExtra);
Das "Handle" zeigt also direkt auf einen Speicherblock.
Mit der Bezeichnung "Handle" wird bloß verschleiert, dass es ein Pointer ist.
HMAllocObject ist hier: http://read.pudn.com/downloads3/sourcecode/windows/248345/win2k/private/ntos/w32/ntuser/kernel/handtabl.c__.htmPVOID HMAllocObject( PTHREADINFO ptiOwner, PDESKTOP pdeskSrc, BYTE bType, DWORD size)
-
Alter Schwede, du bist schon sehr von dir selbst überzeugt, hm?
Winfreak again ... schrieb:
Hier ist die CreateWindow-Funktion
https://github.com/killbug2004/NT_4.0_SourceCode/blob/master/nt4/private/ntos/w32/ntuser/kernel/createw.cDas HWND ist intern ein PWND.
Nein!
Ein PWND ist ein PWND und eben kein HWND. Da gibt es Funktionen die HWND <-> PWND mappen. Und die machen nicht einfach bloss einen Cast.Winfreak again ... schrieb:
Mit der Bezeichnung "Handle" wird bloß verschleiert, dass es ein Pointer ist.
HMAllocObject ist hier: http://read.pudn.com/downloads3/sourcecode/windows/248345/win2k/private/ntos/w32/ntuser/kernel/handtabl.c__.htmFalsch.
Vielleicht solltest du dir mal die Makros _HW, _HWCXX, _HWq etc. - die in dem von dir verlinkten File überall verwendet werden - ansehen.
-
hustbaer schrieb:
Ein PWND ist ein PWND und eben kein HWND. Da gibt es Funktionen die HWND <-> PWND mappen. Und die machen nicht einfach bloss einen Cast.
Ich habs gefunden. Während PWND noch ein echter Pointer auf eine WND Struct ist, ist ein Handle irgend ein DWORD, in dem nur ein Teil (HMINDEXBITS) ein Index zu sein scheint (in ein Array von HANDLEENTRYs).
Hätte nicht gedacht, dass die solche Verrenkungen machen.
Was wohl der Grund sein mag? Ich vermute, das Zeug ist historische gewachsen und es wurde immer mehr dazugebastelt. Dann kommt sowas wohl raus.
-
Winfreak noch immer ... schrieb:
Ich habs gefunden. Während PWND noch ein echter Pointer auf eine WND Struct ist, ist ein Handle irgend ein DWORD, in dem nur ein Teil (HMINDEXBITS) ein Index zu sein scheint (in ein Array von HANDLEENTRYs).
Also das was ich dir bereits geschrieben habe.
Winfreak noch immer ... schrieb:
Hätte nicht gedacht, dass die solche Verrenkungen machen.
Was wohl der Grund sein mag? Ich vermute, das Zeug ist historische gewachsen und es wurde immer mehr dazugebastelt. Dann kommt sowas wohl raus.Nö, das macht voll viel Sinn.
Handles sind prozessübergreifend und du musst sicherstellen können dass der eine Prozess nicht einen anderen Prozess crashen kann indem er irgendwo Mist baut.
Vielleicht solltest du die Selbsteinschätzung deiner Kompetenz neu evaluieren. Du hast offenbar nicht viel Plan davon wie diese Dinge funktionieren, kommst aber trotzdem mit wilden (und völlig falschen) Vermutungen/Behauptungen daher...
-
hustbaer schrieb:
Also das was ich dir bereits geschrieben habe.
In der Tat. Deshalb habe ich die Sache auch weiter verfolgt.
Winfreak noch immer ... schrieb:
Nö, das macht voll viel Sinn.
Handles sind prozessübergreifendGlaubst du denn, dass in dem HWND auch die Process-ID steckt? Das könnte man doch mal nachforschen.
Winfreak noch immer ... schrieb:
Nö, das macht voll viel Sinn.
Glaube ich nicht. Ein Pointer, der in einem anderen Prozess gültig ist, sollte im hiesigen Prozess wie ein "wild pointer" behandelt werden. Dass das Window-Management Aufgaben des Kernels übernimmt, ist ein Designfehler.
Windows ist schon eine tolle Sache. Man sollte seine Entwickler aber nicht für Götter halten.
Winfreak noch immer ... schrieb:
Vielleicht solltest du die Selbsteinschätzung deiner Kompetenz neu evaluieren. Du hast offenbar nicht viel Plan davon wie diese Dinge funktionieren, kommst aber trotzdem mit wilden (und völlig falschen) Vermutungen/Behauptungen daher...
Ist kein Problem. Dazulernen geht immer.
-
WinFreak online schrieb:
Glaubst du denn, dass in dem HWND auch die Process-ID steckt? Das könnte man doch mal nachforschen.
Handles sind prozessübergreifend. Du kannst dir aus Prozess A ein Handle von einem Fenster in Prozess B holen. Da kann keine PID drinstecken.
-
Mechanics schrieb:
Handles sind prozessübergreifend. Du kannst dir aus Prozess A ein Handle von einem Fenster in Prozess B holen. Da kann keine PID drinstecken.
Die APIs, die mit dem HWND arbeiten, müssen letztlich mit anderen Prozessen kommunizieren können. Rohe Pointer sind dafür recht ungeeignet. Wenn ein Fenster eine WM_xxx an ein anderes Fenster schickt, läuft unter Umständen im Hintergrund eine Interprozess-Kommunikation ab.
Windows nutzt für sein Fenstersystem ein Konzept aus "Windowstations" und "Desktops". Das gab es zur Zeit der ersten Windows-Versionen auch noch nicht, wie auch Multiprocessing für Windows unbekannt war.
Windows ist historisch gewachsen, wurde immer weiter aufgerüstet. Perfektes Systemdesign war nie das Ziel, sondern Geld machen mit einem Produkt, das den Kunden gerade so zufrieden stellt.
-
WinFreak not Winfried schrieb:
Perfektes Systemdesign war nie das Ziel [...]
Google mal nach "Dave Cutler"...
-
dot schrieb:
WinFreak not Winfried schrieb:
Perfektes Systemdesign war nie das Ziel [...]
Google mal nach "Dave Cutler"...
Ich kenne das Buch "Showstopper".
Würde ich jedem Windows-Fan empfehlen:
https://www.amazon.com/Showstopper-Breakneck-Windows-Generation-Microsoft/dp/0759285780
-
WinFreak not Winfried schrieb:
... sondern Geld machen mit einem Produkt, das den Kunden gerade so zufrieden stellt.
Gerade so zufrieden ... na ja. Ein Marktanteil von über 90 Prozent bei Desk- und Laptops spricht nicht für "gerade so zufrieden". Der Plan, Geld zu machen, ist also ziemlich gut aufgegangen, würde ich sagen.
Und 9999 von 10000 Kunden kommen mit sowas wie HWND niemals in Berührung, es kann ihnen also völlig latte sein, wie die Dinger zusammengemixt werden.
Dass andere Betriebssysteme viel viel toller sind als Windows, versteht sich von selber. Aber die waren eben, als der Internet-Hype losging, nur für Nerds benutzbar. Computer kaufen und lossurfen ging damit nicht, mit Windows schon. Oder sie waren damals schon teuer und elitär.
-
Printe schrieb:
WinFreak not Winfried schrieb:
... sondern Geld machen mit einem Produkt, das den Kunden gerade so zufrieden stellt.
Gerade so zufrieden ... na ja. Ein Marktanteil von über 90 Prozent bei Desk- und Laptops spricht nicht für "gerade so zufrieden". Der Plan, Geld zu machen, ist also ziemlich gut aufgegangen, würde ich sagen.
Und 9999 von 10000 Kunden kommen mit sowas wie HWND niemals in Berührung, es kann ihnen also völlig latte sein, wie die Dinger zusammengemixt werden.
Dass andere Betriebssysteme viel viel toller sind als Windows, versteht sich von selber. Aber die waren eben, als der Internet-Hype losging, nur für Nerds benutzbar. Computer kaufen und lossurfen ging damit nicht, mit Windows schon. Oder sie waren damals schon teuer und elitär.
Microsoft machte Knebelverträge mit Computerhändlern. Den Kunden wurde Windows einfach untergejubelt. Sogar heute noch ist Windows auf neuen PCs gleich mit drauf. Wenn du einen PC ohne Windows haben willst, guckt der Händler erstmal doof. Viele bieten das nicht einmal an.
Aus dem Grund habe ich mir auch geschworen, für MS-Software niemals Geld auszugeben. Außer Windows benutze ich eh nichts davon.
Internet konnte Windows erst sehr spät. Unter Win3.1 musste man noch das benutzen: ftp://ftp.fh-niederrhein.de/pub/oldstuff/win31/winsock/trumpet/twsk20b.zip
Technologisch gesehen war Microsoft schon immer der Nachzügler. Grafische Benutzeroberfläche ist von Apple abgekupfert, Internet von Unix, C# von Java, usw.
-
Auweia...was für ein Gesülze. Der böse Microsoft-Konzern...blabla. Der Threadstarter hatte nur wissen wollen wie "einzigartig" HWND's sind.
Da ist es völlig egal ob Handle Zeiger auf Typen (struct) sind oder void oder...oder nicht. Die Programmierschnittstelle mit dem Betriebssystem (Windows) ist funktionsorientiert (user32.dll, gdi32.dll, kernel32.dll, opengl32.dll,...).
Ressourcen werden über Funktionen manipuliert, damit Windows weiß welche Ressource (Windows-Objekt) gemeint ist, existieren Handles (Identifikatoren). GDI-Objekte und deren Handle sind z.B. privat für den Prozess. Kernel-Objekte sind spezifisch für den Prozess. User-Objekte unterstützen nur ein Handle per Objekt. Und es ist dabei völlig egal, wie das Handle in C++ umgesetzt ist. Ergo...ja, User-Objekte sind immer "unique". Kernel-Objekte (Prozessrelaitv) können unterschiedlich sein, obwohl die auf die gleiche Ressource verweisen (z. B. Datei).
-
FrankTheFox schrieb:
Kernel-Objekte sind spezifisch für den Prozess.
Falsch.
FrankTheFox schrieb:
Und es ist dabei völlig egal, wie das Handle in C++ umgesetzt ist.
Dir vielleicht.
FrankTheFox schrieb:
Kernel-Objekte (Prozessrelaitv) können unterschiedlich sein, obwohl die auf die gleiche Ressource verweisen (z. B. Datei).
Was soll "prozessrelaitv" heissen? Und wieso schreibst du dauernd Kernel-Objekte wenn du die Handles meinst? Denn die Objekte sind sicher nicht unterschiedliche, das Objekt ist das Objekt und das ist immer das selbe.
Dafür wie du dich hier als "Aufklärer" aufspielst schreibst du überraschend* viel Unfug. Im Endeffekt bist du genau so ein "ich bin wichtig" Quatschlaberant wie WinFreak.
*: Ja, OK, ist gelogen. Überraschend ist es leider überhaupt nicht.