Windows Programming: Learning more about the Win32® API.

Just starting out? Need help? Post your questions and find answers here.
Intrigued
Enthusiast
Enthusiast
Posts: 501
Joined: Thu Jun 02, 2005 3:55 am
Location: U.S.A.

Post by Intrigued »

Thank you for this post, offering!

*thumbs up*
Intrigued - Registered PureBasic, lifetime updates user
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Handling Win API Constants

Post by oldefoxx »

PB will instantly recognize Win API constants if you preceed them with the "#" (pound) character, just as it instantly recognizes Win API procedures if you trail them with a "_" (underscord) character.

Example:
GetStdHandle() in Win32 Help becomes GetStdHandle_()
STD_INPUT_HANDLE in Win32 becomes #STD_INPUT_HANDLE ;Standard input handle
STD_OUTPUT_HANDLE in Win32 becomes #STD_OUTPUT_HANDLE ;Standard output handle
STD_ERROR_HANDLE in Win32 becomes #STD_ERROR_HANDLE ;Standard error handle
has-been wanna-be (You may not agree with what I say, but it will make you think).
josku_x
Addict
Addict
Posts: 997
Joined: Sat Sep 24, 2005 2:08 pm

Post by josku_x »

@oldefoxx: Ofcourse its as simple as that. The Win32 API constants like S_OK is predefined in PureBasic, so because it is a constant, you HAVE to add the # character in front of it, so the compiler recognizes it as a CONSTANT and NOT as a VARIABLE.

So when you just use the constant name without the #, then the compiler searches for a declaration of the variable.
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

josku_x wrote:@oldefoxx: Ofcourse its as simple as that.
He was being helpful for newcomers. :)
--Kale

Image
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Post by oldefoxx »

Exactly.

II have recently been involved in a long internet search for my recluse of a brother. It's way past the time he usually goes before contacting us, and as we get older, the risk that something bad has happened to him increases.

His emails, infrequent, never give any real details about his life. He might say something like: "I'm recovering at home. Nothing else new." And that would be the whole of his email.

As I told my sister, "Dave never bothers to relate what he already knows."

Which includes his address, phone number, state of health, what he is recovering from, what the prognoses might be, and so on. And his email address usually changes from one email to the next. I think he creates a new account each time he decides to send an email, and never bothers to use an existing account again, does not even check it for email trying to reach him.

To me, that is about the ultimate in non-consideration when it comes to being "in touch" with the interests of others. But there are many posters who are equally "out of touch" when it comes to their audience, who may be at a total loss of whatever the @#$% you are talking about.
has-been wanna-be (You may not agree with what I say, but it will make you think).
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Post by oldefoxx »

Okay, next question: How to you relate to a TYPE structure that is used by
the Windows API, without needlessly recreating a new set of Structure and
StructureUnion types? While I wait for someone else to post an answer, I
guess I will do some experimenting on my own.
has-been wanna-be (You may not agree with what I say, but it will make you think).
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Post by oldefoxx »

Okay, I think I have that one too.

To refer to an existing Structure found in the Windows API, you just need to define something like X.structype, where structype is the named type in the Windows API. Most Windows references use the word TYPE instead of the PureBasic's term of Structure, and UNION instead of PB's use of both Structure plus StructureUnion within that structure.

Here is the way the Win32.Hlp describes Small_Rect, which is a structure:

Code: Select all

typedef struct _SMALL_RECT { // srct  
    SHORT Left; 
    SHORT Top; 
    SHORT Right; 
    SHORT Bottom; 
} SMALL_RECT;
Now, right away, we see some problems in trying to use this structure. First, what is a SHORT? Timo Harter produced a file called WinTypes.txt that explains how most Window types can be converted into PureBasic types. It's internal name is "How to use Windows API Types with PureBasic". According to this source, a C/C++ SHORT converts into a WORD type in PB. So instead of saying SHORT Left, we would say Left.w in our structure.

But this brings up another problem, which is that PureBasic has a set of reserved words, and both Left() and Right() are functions in PureBasic. So does naming some fields in this structure the same way cause a problem? To some compilers, such as PowerBasic, it does, because keywords there are universally exclusive, meaning that the context of use ia not considered. Fortunately, this is not true of PureBasic. So no problem there.

The "typedef struc" is actually just "Structure" in Purebasic. the "//" just represents a ";", or comment in PureBasic syntax. The "}" (right curly bracket) near the bottom represents the "EndStructure" statement in PureBasic. So to convert the above into the equivalent format in PureBasic, you would end up with this:

Code: Select all

Structure SMALL_RECT   ; srct  
    Left.w 
    Top.w 
    Right.w 
    Bottom.w 
EndStructure
Note that we dropped the leading underscore to the structure name and the opening curly bracket ({). The information in the Win32.Hlp file is written to support C and C++ programmers, and the syntax they use may seem a bit arcane to PureBasic programmers (or vice versa).

C and C++ are case-sensitive programming languages, and the underscore in front of the structure name is suppose to make it suitable for export. PowerBasic does not require the underscore, and names of variables, structures, and fields are case insensitive.

The really neat thing though, is that PureBasic does not require you to create this structure in your own code - you have access to it by virtue of the power of PureBasic to resolve references to structures defined by the Win32 API automatically. But understanding how C/C++ types convert to PureBasic syntax is necessary in order to make use of them and the fields that they represent.
has-been wanna-be (You may not agree with what I say, but it will make you think).
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Post by oldefoxx »

Next question is, how do you emulate a CallBack (or Hook) procedure in PureBasic? Some of the Windows API calls require that you pass the a procedure pointer to a procedure (in your own code or in a DLL) that it will call automatically, either with the requested information, or when some event transpires (takes place), depending upon the nature of the CallBack process.

CallBack procedures are crutial to handling real time events under Windows, such as processing Mouse movements and buttons, or keyboard presses. Yet at the same time, some part of the Windows API rely on CallBacks just to give you some information from the system, almost like a busy office assistant that tells you she will take care of your request when she finds the time, but she isn't going to do it at this very moment.

A CallBack procedure behaves rather like a WHEN statement. If you say, "When you get home, do your homework", you are defining a future event and what you want to happen when that event occurs. I've often thought that it would be so much easier for people to understand callbacks if they had resorted to a WHEN syntax instead.

A Hook procedure is the same thing. It invokes the image of baiting a fishhook and letting the line just dangle in the water. When a fish rises to the bait and bites, you just reel it in.

Anyway, to make a callback procedure work, it has to be exposed to the event mechanism, or more procisely, the system has to be informed that when the event, next takes place, to make a call to the procedure that has been esxposed to it. It is up to the procedure to then determine if it is to take any action, whether the message it received is intended for it, to forward the message if is not the recipient, to send other messages if so required, and to remove itself from the callback process once it has served its purpose.

I have so far found two references to using CallBack Procedures in PureBasic, but I rather hope someone with more experience will attempt to handle this complex subject.
has-been wanna-be (You may not agree with what I say, but it will make you think).
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8178
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Here's an example of passing a procedure address to a WinApi function. It lists the names of all open windows on your system:

Code: Select all

Procedure GetAllWindows(hWnd, lparam) 
  name.s = Space(100) 
  GetWindowText_(hWnd, @name, 100)
  If Not name
    name = "Not Named"
  EndIf
  Debug Str(hWnd) + ": " + name
  ProcedureReturn #True 
EndProcedure 

EnumWindows_(@GetAllWindows(), 0) 
BERESHEIT
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Post by oldefoxx »

Another issue with Windows API calls is that often, you must supply a string to receive a result. All strings with Windows API use are null-terminated, which is native to C/C++ and PureBasic. An equivalent type with PowerBasic is the ASCIIZ string. However, when you call a Windows API and a string (or buffer) has to receive the result, you must first create a string of sufficient length to receive any possible response, and it must allow a final character of #Null (Chr(0)) value. There are several ways to create an area in memory sufficiently large to receive a returned string, and the called API will conveniently place a #Null character at the end of any valid return.

A common way is to do something like this:

Code: Select all

somestr.s=Space(256)
or like this:

Code: Select all

Define somestr.s{257}
Note that the PureBasic Help file give the correct syntax for the second method, but that it may not be clear that the curly brackets are part of the syntax used.

You can also create a Byte array and pass a pointer reference to it, or use AllocateMemory() to set aside an area of memory to receive the returned characters. There is no one right way to do these things, but there can be some performance and convenience or available function issues involved. The problem with Null-terminated strings is that in some cases, particularly when handling data from non-text files, bytes with a zero value are common. The best course then is to use AllocateMemory() and manage that content via memory references, since this method does not assume that the content represents null-terminated strings.
has-been wanna-be (You may not agree with what I say, but it will make you think).
oldefoxx
Enthusiast
Enthusiast
Posts: 532
Joined: Fri Jul 25, 2003 11:24 pm

Console Screen Reflects Screen Size

Post by oldefoxx »

When you work with the Console, the current screen resolution determines much of what you get as a result. With higher resolutions, the letters that appear on the console are smaller, and you can display more characters per line and more rows when the console window is maximized.

GetSystemMetrics_() can be used to determine what the current screen resolution is, and GetLargestConsoleWindowSize() can be used to determine
the maximum number of lines and rows that can be viewed when the console window is set to its largest size. The console Screen Buffer can be made much larger if you want, in which case the displayed console window will automatically add vertical and horizontal scroll bars as needed.

An even more versitile set of API calls can be found with GetConsoleSystemBufferInfo_() and SetConsoleSystemBufferInfo_(), both of which make use of a structure called ConsoleScreenBufferInfo. This structure can be used to identify or controll the console screen, character
color, and the size of the console screen buffer.

If you make your own grapics window, setting the font, size, and color are easily done. That means you exercise enough control over the console so as to maintain the same appearance, regardless of screen resolution.

If you have Windows XP or Vista, there are some additonal Console commands provided that are not found in some of the earlier windows versions. These are documented on Microsoft's web site, but may limit your ability to distribute your programs. Though I've not explored these added API calls, some of them do deal with Console Fonts.

There are at least two PureBasic libraries released that give you some alternatives for the Console. One is called ConsoleX and the other is called ConsoleEX. You can find these and other libraries for PureBasic at this link: http://www.purearea.net/pb/english/userlibs.php
has-been wanna-be (You may not agree with what I say, but it will make you think).
byo
Enthusiast
Enthusiast
Posts: 635
Joined: Mon Apr 02, 2007 1:43 am
Location: Brazil

Post by byo »

Wow, such well written posts!
I'm not a total newbie on WinAPI but I thought the reading was very helful and better explained than in some books.
User avatar
GeBonet
Enthusiast
Enthusiast
Posts: 135
Joined: Fri Apr 04, 2008 6:20 pm
Location: Belgium

Re: Windows Programming: Learning more about the Win32® API.

Post by GeBonet »

I,
If you do not know : Just a link ... :?:
http://programmingforfun.net/pw5e/pw5e.htm
Bye
Sorry for my english :wink: ! (Windows Xp, Vista and Windows 7, Windows 10)
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Re:

Post by rsts »

removed - had referenced a spam post subsequently removed by mod.
cheers
Last edited by rsts on Sat Jul 24, 2010 4:58 pm, edited 1 time in total.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6076
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Windows Programming: Learning more about the Win32® API.

Post by blueznl »

Keep 'm rolling, people, good stuff to nick and abuse in the guide... :-)
( PB5.xx Win10 x64 Asrock AB350 Pro4 Ryzen 1600X 32GB RAM Evo 840 GTX1060 )
( The path to enlightenment and the PureBasic Survival Guide right here... )
Post Reply