Page 1 of 2
[Solved] How to trick the compiler?
Posted: Sat Sep 18, 2021 7:03 pm
by ZX80
Hello, all.
I would not like to have two executables for my program, but only one. The fact is that for normal operation in new versions of the OS, we had to use an API that XP knows nothing about. Naturally, when running on XP, I get an error. And the method that works in XP is not suitable for newer OS versions.
Question: How to do it universally? Even when I set a condition on which OS the program is running, in XP I still get an error. Could someone provide the simplest example on this subject?
Thank you in advance.
Re: How to trick the compiler?
Posted: Sat Sep 18, 2021 7:31 pm
by Mijikai
I use LoadLibrary_() and GetProcAddress_() to check if a function is available.
Re: How to trick the compiler?
Posted: Sat Sep 18, 2021 11:50 pm
by chi
Code: Select all
Procedure _DwmIsCompositionEnabled(*pfEnabled) : EndProcedure
Prototype _DwmIsCompositionEnabled(*pfEnabled)
dwmapi = OpenLibrary(#PB_Any, "dwmapi")
DwmIsCompositionEnabled__._DwmIsCompositionEnabled = GetFunction(dwmapi, "DwmIsCompositionEnabled")
If DwmIsCompositionEnabled__ = 0 : DwmIsCompositionEnabled__ = @_DwmIsCompositionEnabled() : EndIf
DwmIsCompositionEnabled__(@comp)
Debug comp
If IsLibrary(dwmapi)
CloseLibrary(dwmapi)
EndIf
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 1:45 am
by BarryG
Not the answer you want to hear, but make your app require Win 7 and above. XP is way obsolete, and as you've discovered you're just making unnecessary problems for yourself. Win XP is not even on 1% of worldwide desktop PCs anymore, so why work yourself up over it, or even bother with it?
Source ->
https://gs.statcounter.com/os-version-m ... /worldwide
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 7:33 am
by ZX80
Friends, hello all
Mijikai,
chi,
BarryG, thank you for replying
@
Mijikai
Probably I did not well explain what is required. In this case, I don't need to check that the function exists. This is superfluous, because I know for sure that XP definitely does not have it. The question was how to do the branching. So that there is no mistake when program launched on XP OS. But at the same time, so that the program contains a piece of code for new operating systems. Please, I'm so sorry for my English.
@
chi
This is very similar to what I was looking for. Unfortunately, there is no way to check now. But as soon as I do the check, I will definitely inform you about it. Thanks a lot. As always, you are on top. You understand the problem, although I don't well explain in English. Sorry.
@
BarryG
Thank you for your reply too. You're right, this is really not what I expected to see. Because this does not answer the question posed. XP is already an old lady, I know, but some people still use this OS. Thanks for your answer anyway. And of course I'm sorry for my English.
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 7:58 am
by BarryG
I fully understand what the problem is and I've had it before in the past - just having an unsupported API in my code would stop my exe running on XP at all (Windows wouldn't let the exe run). Is this the problem you're having, or does your exe run on XP with the API in it but not called? Can you post which API command it is so we can help you more?
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 8:19 am
by ZX80
BarryG wrote: Sun Sep 19, 2021 7:58 am
... Can you post which API command it is so we can help you more?
Of course.
You are right, the program stops at the startup phase. Yes, you described the problem correctly. And all because of Drag&Drop, which I use in the program. Everything worked well on XP, 7x86 with a standard approach. But when I accidentally tried it on 8.1 x64, I was surprised that now it doesn't work. I started looking for a solution. It turns out this is a known issue. As a result, this solution worked for me for 8.1 x64:
Code: Select all
ChangeWindowMessageFilter_(#WM_DROPFILES, #MSGFLT_ADD)
ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)
ChangeWindowMessageFilter_(73, #MSGFLT_ADD)
SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_ACCEPTFILES)
...
repeat
...
If Event = #WM_DROPFILES
Dropped = EventwParam()
Num = DragQueryFile_(Dropped, -1, "", 0)
...
I also saw a recommendation to abandon the use of Drag&Drop altogether. But it’s convenient and I didn’t plan to give it up. I don't know how justified the combination of these two methods will be. What do you think?
Second one (for XP):
Code: Select all
If Event = #PB_Event_GadgetDrop
Object$ = EventDropFiles()
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 8:33 am
by ZX80
On MSDN
Requirements:
Minimum supported client - Windows Vista [desktop apps only]
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 9:00 am
by BarryG
ZX80 wrote: Sun Sep 19, 2021 8:19 amEverything worked well on XP, 7x86 with a standard approach. But when I accidentally tried it on 8.1 x64, I was surprised that now it doesn't work.
Wait... now you're saying it worked on XP, but not on 8.1? I'm confused.
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 9:18 am
by ZX80
No contradiction.
Look... I said that the standard way, wich PureBasic offers out
does not work on 8.1 x64. Therefore, I had to look for another solution for this OS. And I found it, but it doesn't work under XP, because XP doesn't know about this API function. The original question was how to combine these two methods. So that the API (for 8.1) used in the general code does not cause an error when launched from under XP. That's all.
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 9:29 am
by BarryG
Oh, okay. Can you maybe post a snippet that compiles to show it working with 8.1 but not XP? I can then try to make it work for you.
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 9:35 am
by ZX80
Okay. Just a second, as the code is redundant. Now I will choose the main thing.
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 9:50 am
by ZX80
This code for VISTA+ OS:
Code: Select all
NewList DroppedFiles.s()
SecondColumnWidth = 250
wflags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 300, "test", wflags)
LIG_ID = ListIconGadget(0, 5, 5, 590, 290, "parameter", 600 - 15 - SecondColumnWidth, #PB_ListIcon_MultiSelect|#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "value", SecondColumnWidth)
ChangeWindowMessageFilter_(#WM_DROPFILES, #MSGFLT_ADD)
ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)
ChangeWindowMessageFilter_(73, #MSGFLT_ADD)
SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_ACCEPTFILES)
Repeat
Event = WaitWindowEvent()
Window = EventWindow()
If Event = #WM_DROPFILES
Dropped = EventwParam()
Num = DragQueryFile_(Dropped, -1, "", 0)
If Num
ClearList(DroppedFiles())
For i=0 To Num-1
Size = DragQueryFile_(Dropped, i, 0, 0)
Object$ = Space(Size)
DragQueryFile_(Dropped, i, Object$, Size+1)
AddElement(DroppedFiles())
DroppedFiles() = Object$
Next
DragFinish_(Dropped)
ClearGadgetItems(0)
ForEach DroppedFiles()
AddGadgetItem(0, -1, DroppedFiles() + #LF$ + "")
Next
EndIf
ElseIf Event = #PB_Event_CloseWindow
Exit = #True
EndIf
Until Exit
EndIf
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 9:57 am
by ZX80
And this one for XP:
Code: Select all
NewList DroppedFiles.s()
SecondColumnWidth = 250
wflags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 300, "test", wflags)
LIG_ID = ListIconGadget(0, 5, 5, 590, 290, "parameter", 600 - 15 - SecondColumnWidth, #PB_ListIcon_MultiSelect|#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "value", SecondColumnWidth)
EnableGadgetDrop(0, #PB_Drop_Files, #PB_Drag_Copy | #PB_Drag_Move)
Repeat
Event = WaitWindowEvent()
Window = EventWindow()
If Event = #PB_Event_GadgetDrop
Object$ = EventDropFiles()
If Object$
Num = CountString(Object$, Chr(10)) + 1
ClearList(DroppedFiles())
For i=1 To Num
AddElement(DroppedFiles())
DroppedFiles() = StringField(Object$, i, Chr(10))
Next
ClearGadgetItems(0)
ForEach DroppedFiles()
AddGadgetItem(0, -1, DroppedFiles() + #LF$ + "")
Next
EndIf
ElseIf Event = #PB_Event_CloseWindow
Exit = #True
EndIf
Until Exit
EndIf
Also it works on Windows 7 x86, but not on 8.1 x64. I can't say anything about windows 10. I have only Windows 7 x86.
Re: How to trick the compiler?
Posted: Sun Sep 19, 2021 10:08 am
by ZX80
Now I think it will be difficult to combine. And the simplest thing is have two files. Separately for NT5 and NT6.
P.S. Why this doesn't work "out of the box" for NT6 x64?
