Hello CTypes

I mean ctypes. Petzold begins his guide with a reference to K&R's classic Hello World. Petzold's version uses the MessageBox function to present the classic inaugural program. My first attempt is:

hello_ctypes.py


import ctypes as c

user32 = c.windll.user32
user32.MessageBoxW(0, "Hello, ctypes", "Hello!", 0)

This is at the same time more concise than the example on page 14 of Programming Windows and more complicated. Python makes it easier to jump right in and call the function. one thing you need to find out is what dll each function defined in the windows api comes from. In this example MessageBox is defined in user32.dll so we get a reference to it using ctypes windll object to load the library. One last complication is the whole MessageBox vs. MessageBoxA vs. MessageBoxW. Petzold doesn't get into it till chapter 2 but because of pythons dynamic nature we have to choose up from which version of the function to use. when programming in C there are macros to translate between the alias MessageBox and it's appropriate counterpart. When people actually programmed against windows 9x the MessageBoxA version would call the ansi c based version of the MessageBox function and on NT version the MessageBoxW version would get called. In 2008 we can safely ignore (at least I can) the ancient version of windows. Because the functions get called by name at runtime we have to choose the MessageBoxW version. I personally feel that this makes the code a little more ugle than it needs to be and adds some complexity we need to address upfront.

First I must introduce you to my convention. Since ctypes is a bridge to c and since I don't relish typing ctypes repeatedly in my code I use the import ctypes as c statement to make it easier to type ctypes as c.

Next I feel that I should use variables that refer to the values I'm using as parameters to MessageBox so here is a cleaned up version of the code:

hello_ctypes.py


import ctypes as c

user32 = c.windll.user32

MB_OK = 0x0
MB_OKCANCEL = 0x1
MB_ABORTRETRYIGNORE = 0x2
MB_YESNOCANCEL = 0x3
MB_YESNO = 0x4
MB_RETRYCANCEL = 0x5

MB_ICONHAND = 0x10
MB_ICONQUESTION = 0x20
MB_ICONEXCLAIMATION = 0x30
MB_ICONASTRISK = 0x40

if __name__ == "__main__":
    user32.MessageBoxW(0, "Hello, ctypes", "Hello!", MB_OKCANCEL | MB_ICONEXCLAIMATION)

changed January 3, 2009