Zaf5 and commctrl.h

Benjamin Riefenstahl benny@crocodial.de
Wed Jan 28 14:54:00 GMT 1998


Hi Alec,


Alec Mihailovs wrote:
> I tried to build Zaf ( http://www.zinc.com/ )
> using gcc 2.8.0 obtained from
>  http://agnes.dida.physik.uni-essen.de/~janjaap/mingw32/index.html
> 
> and it appeared that I need a commctrl.h to do that.
> Could you please give me any advice where I could locate that header?.

See attached my notes about a basic port of ZAF5 to gnu-win32/b18 which
I did in november. Note that I did not do any serious development. It
was more a proof-of-concept effort. Feedback from Zinc at the time was
that they would try to include the small patches mentioned into their
own source.


so long, benny
======================================
Benjamin Riefenstahl (benny@crocodial.de)
Crocodial Communications EntwicklungsGmbH
Ophagen 16a, D-20257 Hamburg, Germany


Subject: Re: Compiling ZAF with gcc on W95
Date:	 Sun, 09 Nov 1997 20:07:36 +0200
From:	 Benjamin Riefenstahl <benny@crocodial.de>
To:	 zaf5-list-outgoing@platinum.zinc.com


Send messages to zaf5-list@zinc.com
Send list maintenance mail to majordomo@zinc.com
Archives are kept at ftp.zinc.com in /zaf/zaf5-list

Hi Folks,


A while ago, John A. Roberts asked if it was possible to compile ZAF5
with GNU-C++ for Windows (the Cygnus port available as a late beta from
www.cygnus.com).

I decided that I would like to know myself if this is possible so I
spent a few hours on this. The result was, it doesn't work out of the
box but with a few tweaks it can be made to work. Note that I only tried
to make the library and build the test program. I did not compile
examples or the test suite.

What did I do and what were the problems?


Win/32 SDK
==========
GNU-C++ does not include the MS SDK for Windows (now called the
"Platform SDK") out of the box. The reason for this is of course that
the SDK is not freely available, so it can not be included with GNU
tools. OTOH the Cygnus port includes a set of selfmade headers to
emulate the SDK to some degree and this actually kind of works. It is
not seemless though and does not support everything that ZAF5 needs.

This means that there are two ways to compile ZAF5 with GNU: If you have
the Platform SDK (it's part of MSDN) one can adapt it to the GNU
compiler, the other way is to add a few lines to the ZAF5 sources to
bridge the differences between what ZAF5 needs and what the Cygnus
emulation delivers. The second method is a bit easier, it just requires
some 15 lines in w_env.hpp and that is that. What I added was

<<<<<<<<
#ifdef  __GNUC__
#define ZAF_POSIX 1

typedef WNDCLASS WNDCLASSA;
typedef OPENFILENAME OPENFILENAMEA;
typedef WIN32_FIND_DATA WIN32_FIND_DATAA;

#define WC_DIALOG ((char*) 0x8002)
const int LOCALE_SINTLSYMBOL = 0x00000015;   /* intl monetary symbol */
const int LOCALE_IINTLCURRDIGITS = 0x0000001A;   /* # intl monetary
digits */

inline HANDLE GetWindowTask( HWND hWnd )
        { return (HANDLE)GetWindowThreadProcessId(hWnd, NULL); }
inline char * AnsiLower ( char * s )
        { return CharLower(s); }
#endif
<<<<<<<<

As you can see there are basically three types of adaptions:
- The Cygnus headers do not have a "Unicode" and an "ANSI" version of
the Win/32 structure definitions as the Platform SDK has. As long as we
only compile for 8 bit, we can just add typedefs to define the "xxxA"
versions of the structs as the plain "xxx" versions (the Platform SDK
does the direct opposite internally). If we wanted Unicode we would have
to find a way to get the Cygnus headers to produce Unicode structures
and "ANSI" structures at the same time.
- The Cygnus headers are missing some constants.
- The Cygnus headers are missing some compatibility function macros.

All in all I just added the missing bits as I went along.


Function pointers
=================
There is a slight problem with the declaration of callback function
pointers. The same problem shows up, when one tries to integrate the
Platform SDK with GNU and I dimly remember that I have it seen with
other compilers too in the past. To be more precise the problem is the
mixture of function pointers and calling convention modifiers. A
callback pointer in the Platform SDK and ZAF5 code typically looks like
this

  BOOL (WINAPI *Ctl3dRegister)(HINSTANCE);

The problem is the placement of WINAPI (which is a macro that translates
to the modifier __stdcall in Win/32). Different compilers have different
ideas where it should go and which of the components of a complex
declaration like this it applies to. The work-around is simple, instead
of using a complex declaration like the above one breaks it down into
two well-defined and well-understood steps:

  typedef BOOL WINAPI Ctl3dRegister_T(HINSTANCE);
  Ctl3dRegister_T * Ctl3dRegister;

In the first step one declares a function type. In this declaration the
placement of the modifier is not in question, all compilers that I know
accept the form given above. In the second step one declares the actual
pointer.

This problem comes up in the ZAF5 code only with the Ctl3d code and a
couple of other function pointers in w_app1.cpp. As described it is
rather simple and mechanically to solve.


Miscellaneous changes
=====================
- The Cygnus headers don't have a header <commctrl.h>, but the
functionality is in their <windows.h> so in w_env.hpp one can just
change

#       include <commctrl.h>

to 

#       ifndef  __GNUC__
#       include <commctrl.h>
#       endif

- In z_stdlib.hpp __GNUC__ needs to be added to the #ifdef which guards
#include <z_unistd.hpp>. This #ifdef should probably be just an #ifdef
ZIL_POSIX anyway. In z_dskfil.cpp __GNUC__ needs to be added to the list
of compilers that do not support <dos.h>.

- In z_unistd.cpp I added #include <stdio.h> to the top of the source,
because rename() is used in the code and somehow there wasn't a
prototype in sight.

- In w_i18n.cpp I replaced a call to strlwr(), which is a function
specific to commercial Windows compilers, with AnsiLower() which is an
SDK function/macro that should be actually more appropriate in this
place anyway.

- In z_utime.cpp after line 21 I added

<<<<<<<<
#       elif defined(__GNUC__)
                extern "C" int gettimeofday(struct timeval *tp, struct
timezone *tzp);
#               include <sys/time.h>
>>>>>>>>


Makefile
========
For this quick try I did not bother to set up a complicated Makefile or
adapt the zmake system. I just used a simple makefile with the effective
compile command

  gcc -DWIN32 -I../include -c $<

the librarian commands

  -rm libzaf5.a
  ar qv libzaf5.a *.o

and the linker command

  gcc -mwindows -o gnutest.exe test.o libzaf5.a -lcomctl32



so long, benny
======================================
Benjamin Riefenstahl (benny@crocodial.de)
Crocodial Communications EntwicklungsGmbH
Ophagen 16a, D-20257 Hamburg, Germany
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".



More information about the Cygwin mailing list