Newbie to Purebasic - API Programming

Just starting out? Need help? Post your questions and find answers here.
PatB
New User
New User
Posts: 2
Joined: Fri Mar 03, 2017 2:05 pm

Newbie to Purebasic - API Programming

Post by PatB »

Hello,

I'm relatively new to PureBASIC, having come from PowerBASIC, GFA-BASIC, C and (many years ago) Assembler.

I'm starting my learning by porting several old programs to PureBASIC but I only use the Win API style. The first thing that gets me is no WinMain() but someone already provided a workaround for that.

The current problem I'm having is with porting to x64 version where the code that returns the program Instance handle no longer works.

Code: Select all

;========================================================================================
; Get hInstance, using in-line assembler. (This'll be interesting!)  Understand hInstance
; is stored in the PureBASIC variable _PB_Instance.  We simply push/pop that into our
; global variable.

! push dword [_PB_Instance]                                 ; Get from PureBASIC
! pop  dword  [v_ghInst]                                    ; Store in global variable
This worked in x32 (if I remember correctly) but not x64. My assembler knowledge is poor now. Can anyone help me out with this?

Regards,


PatB
User avatar
Demivec
Addict
Addict
Posts: 4091
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Newbie to Purebasic - API Programming

Post by Demivec »

PatB wrote:This worked in x32 (if I remember correctly) but not x64. My assembler knowledge is poor now. Can anyone help me out with this?
Use a larger data size for the instance value placed on the stack, instead of dword use qword.

Code: Select all

;========================================================================================
; Get hInstance, using in-line assembler. (This'll be interesting!)  Understand hInstance
; is stored in the PureBASIC variable _PB_Instance.  We simply push/pop that into our
; global variable.

! push qword [_PB_Instance]                                 ; Get from PureBASIC
! pop  qword  [v_ghInst]                                    ; Store in global variable
User avatar
chi
Addict
Addict
Posts: 1034
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Newbie to Purebasic - API Programming

Post by chi »

Win API style

Code: Select all

GetModuleHandle_(0)
Et cetera is my worst enemy
User avatar
blueb
Addict
Addict
Posts: 1044
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Newbie to Purebasic - API Programming

Post by blueb »

PatB wrote:... I'm starting my learning by porting several old programs to PureBASIC but I only use the Win API style. The first thing that gets me is no WinMain() but someone already provided a workaround for that.
Here's a large repository of PureBasic code: http://www.rsbasic.de/backups/

In particular, there's a zipped file of Petzold's 5th Edition book (Petzold.zip) that uses total SDK coding examples using WinMain(), etc. and could be useful in your quest. :)
- It was too lonely at the top.

System : PB 6.10 LTS (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
PatB
New User
New User
Posts: 2
Joined: Fri Mar 03, 2017 2:05 pm

Re: Newbie to Purebasic - API Programming

Post by PatB »

Demivec, thanks. Obvious fix, now that you pointed it out :)

chi - Thanks also. I saw this in many of the examples but my mind is still trying to figure out no WinMain().

blueb - Yes, this is good, thanks.

I can't find references to _PB_Instance, to see what other data is available (like nCmdShow). Am I also missing something fundamental in the docs?

Are there many PureBASIC coders who follow pure API programming style? and how do I find them?


Pat
User avatar
Zebuddi123
Enthusiast
Enthusiast
Posts: 794
Joined: Wed Feb 01, 2012 3:30 pm
Location: Nottinghamshire UK
Contact:

Re: Newbie to Purebasic - API Programming

Post by Zebuddi123 »

Hi PatB. This will give you some idea of how pb works its not upto date but generally most of it is current and sounds like it wouldnt take you long to grasp it :)

zebuddi.
http://www.purebasic.fr/english/viewtop ... willoughby
malleo, caput, bang. Ego, comprehendunt in tempore
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Newbie to Purebasic - API Programming

Post by Marc56us »

Hi PatB,
I'm starting my learning by porting several old programs to PureBASIC but I only use the Win API style
A good way to approach a new language is to begin by listing its possibilities (libraries) rather than trying to translate strictly old codes. :wink:

PB comes with a large amount of functions (> 1400) that cover almost all domains and are mostly compatible with Windows, Linux, Mac, which is not the case if you only program with APIs

We appreciate PB mainly for its conciseness and therefore its productivity, so we avoid as much as possible to use API directly.

Just have a look at: General Libraries
https://www.purebasic.com/documentation/index.html
You will be surprised at the ease and possibilities of programming in PB without using the API directly

Example: the minimum Windows (and Linux and Mac!) application in PB: 2 lines

Code: Select all

OpenWindow(0, 0, 0, 500, 300, "Hello World!")

While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
How many line to do it with API only ? :shock:

This is one of the few languages with which programming becomes a pleasure
And many users of PB have used quite a lot of other languages for several decades sometimes

Welcome and enjoy.
:wink:
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: Newbie to Purebasic - API Programming

Post by nco2k »

chi wrote:GetModuleHandle_(0)
not the same, when using a dll at least. GetModuleHandle_() will return the hInstance of the executable that loaded the dll and not the hInstance of the dll itself. so if you have a dll and want to create a window inside it, you shouldnt use GetModuleHandle_() for that.

i would use this:

Code: Select all

Import ""
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !PUBLIC _PB_Instance As "_MyInstance"
  CompilerElse
    !PUBLIC PB_Instance As "MyInstance"
  CompilerEndIf
  MyInstance
EndImport
Debug MyInstance
c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
chi
Addict
Addict
Posts: 1034
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Newbie to Purebasic - API Programming

Post by chi »

Win API style ;)

Code: Select all

GetModuleHandle_(ProgramFilename())
or

Code: Select all

Enumeration
  #GET_MODULE_HANDLE_EX_FLAG_PIN = 1
  #GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 2
  #GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = 4
EndEnumeration

Import "kernel32.lib"
  GetModuleHandleExW(dwFlags.i, lpModuleName.s, hModule.i)
EndImport

Define hModule.i
GetModuleHandleExW(#GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|#GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "", @hModule)

Debug hModule
Et cetera is my worst enemy
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Newbie to Purebasic - API Programming

Post by Mijikai »

There are many contradicting infos out there... so what to use?
For me it seems that it doesnt matter since all methods give the same result!?

Testcode:

Code: Select all


EnableExplicit

Import ""
  Instance
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !PUBLIC _PB_Instance As "_Instance"
  CompilerElse
    !PUBLIC _PB_Instance As "Instance"
  CompilerEndIf
EndImport

Import "kernel32.lib"
  GetModuleHandleEx_.i(dwFlags.i,*lpModuleName,*phModule) As "GetModuleHandleExW"
EndImport

Procedure.i Test1()
  ProcedureReturn GetModuleHandle_(#Null$)
EndProcedure

Procedure.i Test2()
  Protected instance.i
  GetModuleHandleEx_(6,@Test2(),@instance)
  ProcedureReturn instance
EndProcedure

Procedure.i Test3()
  Protected instance.i
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !push dword [_PB_Instance]
    !pop dword [p.v_instance]
  CompilerElse
    !push qword [_PB_Instance]
    !pop qword [p.v_instance]
  CompilerEndIf
  ProcedureReturn instance
EndProcedure

If OpenWindow(0,0,0,320,200,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  Debug Test1()
  Debug Test2()
  Debug Test3()
  Debug Instance
  Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
  CloseWindow(0)
EndIf

End
So what to use?
User avatar
mk-soft
Always Here
Always Here
Posts: 5406
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Newbie to Purebasic - API Programming

Post by mk-soft »

Code: Select all

EnableExplicit

Procedure.i GetInstance()
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !mov eax, dword [_PB_Instance]
  CompilerElse
    !mov rax, qword [_PB_Instance]
  CompilerEndIf
  ProcedureReturn
EndProcedure

If OpenWindow(0,0,0,320,200,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  Debug GetInstance()
  Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
  CloseWindow(0)
EndIf

End
Last edited by mk-soft on Sat Oct 17, 2020 5:51 pm, edited 1 time in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Newbie to Purebasic - API Programming

Post by Mijikai »

thx :)
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Newbie to Purebasic - API Programming

Post by Mijikai »

mk-soft wrote: Sat Oct 17, 2020 12:53 pm

Code: Select all

...
Procedure.i GetInstance()
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !mov eax, dword [_PB_Instance]
  CompilerElse
    !mov rax, qword [_PB_Instance]
  CompilerEndIf
  ProcedureReturn
EndProcedure
...
How would that look like in insane C-ASM?
Why is there no offical PB Function for this... :!: :?:
User avatar
mk-soft
Always Here
Always Here
Posts: 5406
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Newbie to Purebasic - API Programming

Post by mk-soft »

Code: Select all

Procedure.i GetInstance()
  CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
    CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
      !mov eax, dword [_PB_Instance]
    CompilerElse
      !mov rax, qword [_PB_Instance]
    CompilerEndIf
    ProcedureReturn
  CompilerElse
    !return PB_Instance;
  CompilerEndIf
EndProcedure

Instance = GetInstance()

Debug Instance
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Newbie to Purebasic - API Programming

Post by Mijikai »

Thanks but it doesnt work - Error:
Constant not found: #PB_Compiler_Backend.

Im using PureBasic 6.00 LTS with C Backend Alpha 1
Post Reply