Author Topic: A clock in WPS - Educational Project  (Read 12308 times)

Martin Iturbide

  • OS2World NewsMaster
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4712
  • Karma: +41/-1
  • Your Friend Wil Declares...
    • View Profile
    • Martin's Personal Blog
Re: A clock in WPS - Educational Project
« Reply #15 on: May 23, 2020, 11:16:23 pm »
Hi

sc.exe compiler worked and generated me the CPP, XH and XIH files.

Now I want to compile it (icc.exe), but no luck yet. I tried to make a basic make file based on HWman, but Im still clueless. (file inside the attachment)
What command and arguments do you recommend to compile this exercise?

The other thing that Im clueless is how to reference the resource GUI files (3 screens) with the three methods, so it can be displayed once the class is registered and the object created.

Regards
« Last Edit: May 23, 2020, 11:36:25 pm by Martin Iturbide »
Martin Iturbide
OS2World NewsMaster
... just share the dream.

Lars

  • Hero Member
  • *****
  • Posts: 1271
  • Karma: +65/-0
    • View Profile
Re: A clock in WPS - Educational Project
« Reply #16 on: May 24, 2020, 10:23:55 am »
1) do not specify -D__IBMC__ when calling the compiler. That defeats the whole purpose of compiling C++ code as this define is set when the C-compiler is run but not the C++.compiler

2) you are now entering into the dark realms of SOM programming. What you are missing in particular is to include <os2.h> in your code (and defining the proper defines INCL_BASE and INCL_PM) because even the generated code refers to datatypes that are defined in the OS/2 include files.
You could now do this in two ways:
add
#define INCL_BASE
#define INCL_PM
#include <os2.h>
in your c++ source file, even before including "xwpclock.xih". That is easy but is has the negative impact that you have to do that manually and it might get acidentally removed by sc.exe.
or:
you add some "instrumentation" in your .idl file that tells sc.exe to automatically generate these statements into your c++ source file:
        passthru C_xh_before = ""
        "#define INCL_PM"
        "#define INCL_BASE"
        "#include <os2.h>"
        "";
That will place these statements into xwpclock.xh (at the correct place) which is included by xwpclock.xih.
You will have to read the SOM programming documentation to understand what's going on, hint: "xih" is the implementation header which is used by the guy implementing the class, "xh" is the public definition header used by the guy using the class in his own code and the guy implementing the class.

3) in your .rc file you misspelled the . h file you intend to include. Therefore you will get an error on building

4) in your .h file you missed to define DLG_XWPCLOCKTIME and possibly others. The resource compiler gives a bogus warning because it thinks that identifier is a string (where it should be the define for a number)
etc.

5) when you actually want to use resources (like a dialog), you will need to query the module handle of your own DLL because that module handle will need to be passed to OS/2 API functions creating dialogs (like WinLoadDlg etc.) and then to specify the ID of the resource/dialog, like DLG_XWPCLOCKALARM. In order to do that you will need to include the xwpclock-resources.h not only in your .rc file but also in the c++ source file. Again, you can hack that in manually or have it done via the .idl file.

6) There are multiple ways to query your own module handle: you either write a custom _DLL_InitTerm function to get to the handle (which is the most forward way for me, but maybe not to others,see the hwman sample code) or you can use SOM method "somLocateClassFile" plus OS/2 API function "DosGetModuleHandle" to get to the module handle:

HMODULE gModule = NULLHANDLE; /* needs to be placed somewhere into the data segent and NOT on the stack ! */

PSZ ModName=NULL;
somId theId = somIdFromString("XWPClock");
ModName = SOMClassMgr->somLocateClassFile(theId,XWPClock_MajorVersion,XWPClock_MinorVersion); /* you need to include <somcm.xh> */
SOMFree(theId);
DosQueryModuleHandle(ModName,&gModule); /* gModule now contains your module handle */

It should be obvious to you that you will need to fix this piece of code once you change your class name to something else. Maybe you now see why I always go for the custom _DLL_InitTerm function ...

« Last Edit: May 24, 2020, 10:42:09 am by Lars »

Martin Iturbide

  • OS2World NewsMaster
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4712
  • Karma: +41/-1
  • Your Friend Wil Declares...
    • View Profile
    • Martin's Personal Blog
Re: A clock in WPS - Educational Project
« Reply #17 on: June 04, 2020, 04:48:58 pm »
Thanks Lar's for the reply.
I'm going slowly no this but I think I'm getting it.

I understood and made some changes from #1 to #5, but I don't get the #6 "Querying your own module handle".
For the moment I'm not going with the "custom _DLL_InitTerm function", but with the SOM Method + API Call that you posted.

Quote
HMODULE gModule = NULLHANDLE; /* needs to be placed somewhere into the data segent and NOT on the stack ! */
Here I'm confused on where/what is the Data Segment and where is the stack. Where should I put this?

Quote
PSZ ModName=NULL;
somId theId = somIdFromString("XWPClock");
ModName = SOMClassMgr->somLocateClassFile(theId,XWPClock_MajorVersion,XWPClock_MinorVersion); /* you need to include <somcm.xh> */
SOMFree(theId);
DosQueryModuleHandle(ModName,&gModule); /* gModule now contains your module handle */
Also here should I put this?

Thanks for your help.

Regards


Martin Iturbide
OS2World NewsMaster
... just share the dream.

Lars

  • Hero Member
  • *****
  • Posts: 1271
  • Karma: +65/-0
    • View Profile
Re: A clock in WPS - Educational Project
« Reply #18 on: June 04, 2020, 05:35:43 pm »
1) data segment: if you define a global variable or define with "static" keyword. Stack: a lokal variable in a routine is placed on the stack.

2) you have these 2 options: put gModule in the data seg and call the code to query it only once on class initialization (read SOM spec what class init is and when it happens) or call code whenever you need the module handle in which case you can place gModule on the stack.