OS2 World Community Forum

OS/2, eCS & ArcaOS - Technical => Programming => Topic started by: Martin Iturbide on May 08, 2020, 01:22:17 am

Title: A clock in WPS - Educational Project
Post by: Martin Iturbide on May 08, 2020, 01:22:17 am
Hi

I still want to try to make my first WPS application. But I need to learn more on how to make an WPS app, so I guess my first step will be to set a goal.

My goal will be to create a WPClock clone called XWPClock as a child of WPAbstract (and not as a child of WPClock).

I'm thinking, as a first stage, to have some kind of application skeleton first. Like having the .IDL file of the XWPClock class and a initial GUI that can be compiled, but without the logic of a working app.

I just want to create the XWPClock class with three tabs and some controls (checkboxes, label, etc), but with no logic first. Like it is a mockup screen but in a DLL that can be registered on the WPS.

Will it be ok to use the Resource Editor (dlgedit.exe) to create the GUI? I see that Doodle Screen Saver uses it. Is there any other technique suggested for the GUI?

Regards
Title: Re: A clock in WPS - Educational Project
Post by: Andi B. on May 08, 2020, 12:08:33 pm
Have you looked at URE - Universal Ressource Editor? Should be on hobbes. But aren't the option already listed on edm2?
Title: Re: A clock in WPS - Educational Project
Post by: Dave Yeo on May 08, 2020, 04:18:09 pm
URE is what Doodles Screen Saver used.
Title: Re: A clock in WPS - Educational Project
Post by: Martin Iturbide on May 08, 2020, 04:36:59 pm
Thanks for the feedback back. I will check it.
Now I get why the files from DoodleSS looked funky on Resource Editor (dlgedit.exe).

I will give it a try to the "Universal Resource Editor", I guess it produces the .RC (Resource Script) and .H  standard to be compiled without anything special later.

Suggestions are welcome while I test URE.

Regards
Title: Re: A clock in WPS - Educational Project
Post by: Dave Yeo on May 08, 2020, 05:08:33 pm
Thanks for the feedback back. I will check it.
Now I get why the files from DoodleSS looked funky on Resource Editor (dlgedit.exe).

I will give it a try to the "Universal Resource Editor", I guess it produces the .RC (Resource Script) and .H  standard to be compiled without anything special later.

Suggestions are welcome while I test URE.

Regards

Yes, it basically creates the .RC and .H as well as a .URF file, the RC and H should be all that is needed along with a resource compiler such as rc.exe or wrc.exe.
Title: Re: A clock in WPS - Educational Project
Post by: Martin Iturbide on May 16, 2020, 11:22:08 pm
Hi

I created  simple GUI with URE for the three notebook pages (is it called that way?) that I want to have on XWPClock. The GUI is still ugly and incomplete, but my goal is just to try to compile a WPS object and register it, without having the full program logic inside it yet.

I need some help please. Can someone help with the procedure to compile a XWPCLOCK.DLL file, so I can be able to register a WPS class that shows the GUI. (the notebook pages). I really have no idea of the compile process or how to create the make file.

Just suggest me the procedure (with details please) and I would get the needed tools. Right now I have the "IBM C and C++ Compilers Version 3.6.5".

Regards
Title: Re: A clock in WPS - Educational Project
Post by: Dave Yeo on May 17, 2020, 01:34:43 am
Why not look at the various samples? There's some in the toolkit under samples\wps, same ones in IBMCPP but really should use the newer toolkit ones along with using the toolkit for everything else.
Perhaps OpenWatcom would be a better choice, still might want to use the toolkit along with it, especailly if needing the SOM compiler. At least it is freely available and seems to have better samples under samples\os2, especially the wps sample.
BTW, the full name would the Properties notebook pages
Title: Re: A clock in WPS - Educational Project
Post by: Lars on May 17, 2020, 11:32:01 am
My HWMAN class comes with full source code and a makefile for VAC 3.x. That is close enough to VAC 3.6.x and should serve as a template.
By the way: if you have VAC 3.6.x installed plus the OS/2 Toolkit then you have all the tools and files that you need.
Title: Re: A clock in WPS - Educational Project
Post by: Martin Iturbide on May 18, 2020, 04:41:48 pm
Hi

I'm trying to understand what are the steps that I need to do from this point.
Right now I have the IDL file and the RES files and I want to have a XWPCLOCK.DLL. I only looking for the basic thing to have a WPS object that can be register and only with three tabs with some controls that still does nothing.

 I guess that the order will be to:
- sc compiler
- icc compiler
- rc compiler
- use the linker to produce "XWPCLOCK.DLL"

Now I need to know the parameters. I will be checking HWMAN make file and ask about it.

I had been reading on how to use the sc.exe compiler.
If I run:
  sc.exe -s"h;ih;c" xwpclock.idl
It will create me the .c .h and .ih file from the .idl.  Do I have to run this only once? since I guess I eventually will need to add more logic to the .c file, right?
Does it also applies for C++ ? or I need different parameters on sc.exe ?

Regard
Title: Re: A clock in WPS - Educational Project
Post by: Martin Iturbide on May 18, 2020, 04:45:46 pm
Hi Dave

BTW, the full name would the Properties notebook pages

I didn't get this one? What does it means.

I still do not know where to match that "DLG_XWPCLOCKALARM" (from the RES file) is the "xwpAddClockAlarmPage" method. I'm getting it right or I'm just making non-sense?

Regards
Title: Re: A clock in WPS - Educational Project
Post by: Dave Yeo on May 18, 2020, 05:00:22 pm
Hi Martin, I was answering this question,
Quote
I created  simple GUI with URE for the three notebook pages (is it called that way?) that I want to have on XWPClock.

Not an expert on this stuff but I notice the screensaver compiles the idl with this command
Code: [Select]
@echo Creating header file from IDL file...
sc -mnotc -maddstar -mpbl -s"h;ih" WPSSDesktop.idl

Doodle never did get around to writing a makefile for WPSDesktop, just a batch file which might be a good beginning for you. Write batchfile that does the
Quote
- sc compiler
- icc compiler
- rc compiler
- use the linker to produce "XWPCLOCK.DLL"

Then convert to a makefile.
Title: Re: A clock in WPS - Educational Project
Post by: Rich Walsh on May 19, 2020, 07:16:30 pm
Martin, add the following to your environment before compiling. They set default commandline options and directories:

SET SMNOTC=1
SET SMADDSTAR=1
SET SMEMIT=C;H;IH;DEF;
SET SMTMP=%TEMP%
SET SMINCLUDE=.;%TOOLKIT%\SOM\INCLUDE;%TOOLKIT%\IDL;%TOOLKIT%\H;
(this last line assumes you also have a "SET TOOLKIT=<path>" in the environment)

When compiling, use:  "sc -r -S128000 -C128000 <file>"

One other thing... since this project isn't associated with XWP, it would be better to use a different prefix for its files and classes. Perhaps "MIClock" would be more appropriate (especially in Spanish).
Title: Re: A clock in WPS - Educational Project
Post by: Lars on May 20, 2020, 07:58:08 pm
1) the sc.exe compiler is a smart tool that will be able to update your header and source files when the associated IDL file has changed. If you then rerun sc.exe, it will try to figure out what has changed (as far as the interface that the IDL file defines is concerned) and update your header and source files. Note that sc.exe will NEVER muck with your implementation (the code you added to the method stubs that sc.exe generates), at least not on purpose.
That said, beware: sc.exe is not perfect.

2) I strongly suggest to use the C++ emitter even if you do not want to code in C++ but only in C. The C++ emitter will create stub code that will allow you to call a method on the somSelf pointer which, for an object oriented approach which SOM is pursuing, is a meaningful and sensible thing to do. See the HWMAN source code and you will understand what I mean.
So instead of doing this call with the C bindings:
_wpPopulate(somSelf,0,NULL,FALSE);
you do this with the C++ bindings:
somSelf->wpPopulate(0,NULL,FALSE);

If you want to generate C++ headers and source files you do this:
sc.exe -C200000 -S200000 -scx;xh;xih xwpclock.idl


Lars
Title: Re: A clock in WPS - Educational Project
Post by: Martin Iturbide on May 21, 2020, 12:36:15 am
Thanks for the feedback.
When compiling, use:  "sc -r -S128000 -C128000 <file>"
It worked with this command to generate the .c, .h and .ih file.

One other thing... since this project isn't associated with XWP, it would be better to use a different prefix for its files and classes. Perhaps "MIClock" would be more appropriate (especially in Spanish).
Yes, I will change it. For this thread I'm going to keep it as XWPClock, but I think if I wrote some article I will rename it to SWPCLOCK. (S = Sample).

If you want to generate C++ headers and source files you do this:
sc.exe -C200000 -S200000 -scx;xh;xih xwpclock.idl
Yes, I want to go the C++ way.

I'm getting this error:
Code: [Select]
"xwpclock.idl", line 156: fatal error: Cannot load emitcx.

I guess I'm missing something on the libpaths?

Regards
Title: Re: A clock in WPS - Educational Project
Post by: Lars on May 21, 2020, 08:08:10 am
No you are not missing anything. It was a typo :-).
Should be
sc.exe -sxc;xh;xih ...
Title: Re: A clock in WPS - Educational Project
Post by: Martin Iturbide 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
Title: Re: A clock in WPS - Educational Project
Post by: Lars 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 ...

Title: Re: A clock in WPS - Educational Project
Post by: Martin Iturbide 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


Title: Re: A clock in WPS - Educational Project
Post by: Lars 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.