Subject: Re: Zaf5 and commctrl.h
From: [email-masked] (Thomas Nichols)

29 Jan 1998 01:32:59 -0800
Message-ID: <[email-masked]>
References: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
To: Alec Mihailovs <[email-masked]>,
        Jan-Jaap van der Heijden <[email-masked]>
Cc: GNU-Win32 list <[email-masked]>

At 14:20 27/01/98 -0500, Alec Mihailovs wrote:
>Hello,
>
>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?.
>
>Thank you,
>and have a nice day,
>
>Alec Mihailovs
>http://www.math.upenn.edu/~mihailov/
>
>Attachment Converted: "d:\net\eudora\users\[email-masked]\attach\vcard5.vcf"

Alec,

There are a few things you need to sort out to get this working - but once
done, it seems to be functional. The ZafImage stuff is still broken,
haven't checked why yet.

I asked permission from Benjamin Riefenstahl to post the following message,
originally posted to the Zaf5 mailing list (possibly the closed one) re
porting to CygWin32 b18 (I came to just about the same solutions, but his
is much tidier - I had a dummy "commctrl.h" with all of the extra
definitions in.)

I had to make some fairly trivial mods to get it to work with mingw32 2.8.0
-- I don't have them to hand, please mail me if you want them.

Zinc's ZMAKE does not support GCC on WinNT - I suggest you use GNU gmake,
and make minor modifications to Zinc's POSIX.MAK makefiles - I can post the
required tweaks if you need them.

Hope it works well for you - Zinc is a splendid tool. And it's free! (well,
for personal use, anyway...)

Here's Benny's message:

// ------------ quoted message ------------- //

X-Sender: [email-masked]
X-Mailer: Windows Eudora Light Version 3.0.1 (32)
Date: Mon, 17 Nov 1997 12:42:08 +0000
To: [email-masked]
From: Benjamin Riefenstahl <[email-masked]> (by way of Tom Nichols
<[email-masked]>)
Subject: Re: Compiling ZAF with gcc on W95

Send messages to [email-masked]
Send list maintenance mail to [email-masked]
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 ([email-masked])
Crocodial Communications EntwicklungsGmbH
Ophagen 16a, D-20257 Hamburg, Germany

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".