activex.pp DosDateTimeToVariantTime definition problem lazarus / 67-Windows ---------------------------------------------------------------------- 440bx · 2025-07-13 09:54 Hello, in activex.pp, DosDateTimeToVariantTime is defined as: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function DosDateTimeToVariantTime( wDosDate: ushort; wDosTime:ushort;pvtime:pdouble):longint; stdcall; external oleaut32dll name 'DosDateTimeToVariantTime'; Note the result type of "longint".  This result type is incorrect. The documentation page: https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf- oleauto-dosdatetimetovarianttime shows the function definition to be: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i INT DosDateTimeToVariantTime(  [in]  USHORT wDosDate,  [in]  USHORT wDosTime,  [out] DOUBLE *pvtime); which is also incorrect. The same page describes the return value: QuoteThe function returns TRUE on success and FALSE otherwise. That's a BOOL (or possibly boolean), not an INT. To determine which one is correct, inspection of the function's dis- assembly (partial) shows the following: Code: ASM  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i .text:100169DF                 call    _ErrPackDate@20 ; ErrPackDate(x,x,x,x,x).text:100169E4                 test    eax, eax.text:100169E6                 jnz     short loc_100169FF.text:100169E8                 fld     [ebp+var_24].text:100169EB                 inc     eax.text:100169EC               fstp    qword ptr [ebx].text:100169EE.text:100169EE loc_100169EE:                           ; CODE XREF: DosDateTimeToVariantTime(x,x,x)+D1↓j.text:100169EE                 mov     ecx, [ebp+var_4].text:100169F1                 pop     edi.text:100169F2                 pop     esi.text:100169F3               xor     ecx, ebp        ; StackCookie.text:100169F5               pop     ebx.text:100169F6                 call    @__security_check_cookie@4 ; __security_check_cookie(x).text:100169FB                 leave.text:100169FC                 retn    0Ch.text:100169FF ; ------------------------------------------------- --------------------------.text:100169FF.text:100169FF loc_100169FF:                         ; CODE XREF: DosDateTimeToVariantTime(x,x,x)+74↑j.text:100169FF                                       ; DosDateTimeToVariantTime(x,x,x)+84↑j ....text:100169FF                 xor     eax, eax.text:10016A01               jmp     short loc_100169EE.text:10016A01 _DosDateTimeToVariantTime@12 endp.text:10016A01 The dis-assembly clearly shows that the function returns 1 when successful and 0 upon failure, this fits a BOOL. As currently defined, there is room for the result to be misinterpreted depending on how the comparison is done against the "supposed int". HTH. ---------------------------------------------------------------------- Thaddy · 2025-07-13 11:05 This stems (both issues) from C(++) compilers interpreting false as zero and anything else a valid true. Predates compilers with _Bool. As such it was correct at the time as BOOL (Uppercase and without underscore) was a type macro over longint. ---------------------------------------------------------------------- ASerge · 2025-07-13 16:35 Quote from: 440bx on July 13, 2025, 11:54:32 amThe documentation page: ... ...which is also incorrect. This is the official documentation, so we need to rely on it, despite the current implementation. And it's not that hard, instead Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if DosDateTimeToVariantTime(...) thenwrite it as Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if DosDateTimeToVariantTime(...) <> 0 then ---------------------------------------------------------------------- 440bx · 2025-07-13 16:43 Official or otherwise, it's incorrect. A longint does not have the semantic properties of a boolean. In addition to that, the documentation contradicts itself.  In one place it shows the return value as being an int and then it states it is a boolean. Look at the code to figure out which one is right and boolean is right, int is incorrect and leaves room for an improper comparison that would yield incorrect results. ---------------------------------------------------------------------- PascalDragon · 2025-07-13 17:08 Quote from: 440bx on July 13, 2025, 11:54:32 amThe documentation page: https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf- oleauto-dosdatetimetovarianttime shows the function definition to be: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i INT DosDateTimeToVariantTime(  [in]  USHORT wDosDate,  [in]  USHORT wDosTime,  [out] DOUBLE *pvtime); which is also incorrect. The actual header OleAuto.h (not the documentation) nevertheless declares it as INT, not as BOOL. It doesn't matter whether the return values are provided using the TRUE and FALSE macros inside DosDateTimeToVariantTime (and its inverse), the decaration is nevertheless INT. Yes, that could be misinterpreted, but one is supposed to use MSDN when working with the Windows API anyway. ---------------------------------------------------------------------- 440bx · 2025-07-13 18:11 I know all that.  The header is incorrect.  An int type isn't a two value type. Quote from: PascalDragon on July 13, 2025, 07:08:25 pmYes, that could be misinterpreted, but one is supposed to use MSDN when working with the Windows API anyway. In general I completely agree with that _except_ when the stuff is wrong.  Having correct definition is more important than header files and/or msdn. ---------------------------------------------------------------------- nanobit · 2025-07-13 18:23 In Windows SDK, uppercase FALSE (0), TRUE (1) are integer-constants. ---------------------------------------------------------------------- PascalDragon · 2025-07-15 19:58 Quote from: 440bx on July 13, 2025, 08:11:01 pmThe header is incorrect. The header files are the official source for the Windows API, not a disassembly of the binary and its the official headers that the API translations are based on. ---------------------------------------------------------------------- 440bx · 2025-07-15 21:16 Quote from: PascalDragon on July 15, 2025, 09:58:59 pmThe header files are the official source for the Windows API, not a disassembly of the binary and its the official headers that the API translations are based on. In that case Astronomers and Paleontologists should read the bible to get the "official" (not to mention _sacred_) information about Earth's place in the universe and the origin of the species. Just for fun... here is another definition that, at least in Pascal, is incorrect: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function ListView_GetItemIndexRect(hwnd:hwnd; plvii:PLVITEMINDEX; iSubItem:clong; code:clong; prc:LPRECT) :BOOL; It's incorrect because it is a faithful translation of the C macro. The documentation defines the macro as: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i BOOL ListView_GetItemIndexRect(  [in]      HWND        hwnd,  [in]      LVITEMINDEX *plvii,  [in]      LONG        iSubItem,  [in]      LONG      code,  [in, out] LPRECT      prc); and states the following about the last parameter "prc" Quote [in, out] prc Type: LPRECT A pointer to a RECT structure to receive the coordinates. The caller is responsible for allocating this structure. prc must not be NULL. Emphasis mine.  It "kinda" makes sense for the last parameter not to be NULL/nil given that the purpose of the macro/function is to retrieve the rectangle values (it would be "difficult" to get the rect if passing nil as the place to store it.) The C definition is "correct" because C does not have the means to enforce the condition that the parameter must not be nil but, Pascal does.  The Pascal definition is incorrect, it should specify "var" for the last parameter. Official, sacred... etc, don't make things right. ---------------------------------------------------------------------- marcov · 2025-07-16 09:20 Commctrls was semi automated translated with various bits of Pascal code back then. Anyway, I fully agree with PascalDragon. And in this particular case, while it might be semantically closer, it breaks 1:1 converting existing (example) code. ---------------------------------------------------------------------- 440bx · 2025-07-16 12:09 It's quite obvious that most of the API definitions were automatically generated to some extent, e.g, the use of MS disturbingly poor parameter names.  That's very obvious because there is no attempt whatsoever to cleanup MS' definition mess, e.g, close to a dozen superfluous type names for the same data type and, type names that have no business existing in Pascal, e.g, tagSomeName. It really makes no sense to protect mistakes and gross deficiencies.  Definitions that are incorrect should be corrected.  Things should be improved.  If making it correct breaks some code then that code should be corrected too. Another case like that is WriteFile, the current definition is incorrect but, I know that's another one that is not going to change and, _all_ the definitions that use untyped parameters are semantically incorrect because there is no such thing nor equivalent in C nor C++.  I'm not the only programmer who has written perfectly good code that ended up causing access violations because of those incorrect definitions (which are unfortunately here to stay.) I know, this situation isn't going to change.  Somehow some mistakes are sacred and must be preserved.  Anyway, I'll keep reporting the mistakes as a courtesy.  I have to admit that I'm still not used to seeing mistakes defended and preserved.