We value your input!
Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey

Archicad C++ API
About Archicad add-on development using the C++ API.

[newbie] how about 'hello world'

Anonymous
Not applicable
When I wrote my introduction to the forum, Karl said
Looking at the PDF link that you posted, I think you're in for some "fun", Tor Jørgen! Welcome!
I'm glad for the welcome, but I worry that maybe I'm in over my head - I guess thats where the fun starts...

I'll just wait with the questions connected with my project and start really simple;

- in most of the languages I've looked at, there's always an example of how to write the simple 'hello world'-snippet. How do I do that in an addon?
- and then how does the real workprocess go, I'm thinking of debugging and setting breakpoints and beeing able to step through the code to see what happens where, and why... and how is the interaction with ArchiCAD?

--
Regards,
Tor Jørgen
41 REPLIES 41
Andras Babos
Graphisoft Alumni
Graphisoft Alumni
stefan wrote:
STEP 2 : creating a skeleton addon

(I'll explain it for Windows, but I guess it won't be too much different on the Mac)

In Visual Studio 6.0 you can create a new ArchiCAD Add-on with the provided wizard. Select the API DevKit folder and (optionally) add support for dialogs & input/output. We won't need them for "Hello World".

Let it generate a complete project and try to compile. It won't work!
RFIX.WIN\..\Debug\HelloWorldFix.grc.rc2 (26): error RC2104 : undefined keyword or key name: WIN_LANGUAGE_ID
Add the Developer ID

...

Correct the missing keywords

This part is what I am not so sure about, but I've got it to work, so here it goes: the WIN_LANGUAGE_ID which is not recognised is actually defined in "GSLocalization.h". This file is included in the "HelloWorldFix.grc" file, which is used by the "Resource Conversion" program to generate a real resource file: "HelloWorldFix.grc.rc2".

In the localization header, we can see some info about the different language versions of ArchiCAD. I wasn't so sure how to solve it, but I tried and the following got it going: I added a few extra defines in my header files, so the included Localization file can derive the correct definitions. Inside "HelloWorld.rc2" I added a few lines like this, after the #include <Windows.h>:
#include <Windows.h>

#define INT__APP
#define INTERNAL_NAME "HelloWorld"
#define ORIGINAL_NAME "HelloWorld.apx"

#if !defined (WINDOWS)
#define WINDOWS
#endif
I guess the strings don't matter that much, but the first define made the lookup in the Localization header work.

And yes, now it compiles fine.

checking the compiled APX

...
OK, I've looked into this (as I'm responsible for that AppWizard since I've created it ... ). The problem seems to be the following:
Back then when the 8.x DevKits were released we were in a bit of a hurry (as usual ), so when we added 'VERS' (version) resources to the AppWizard generated code we didn't check that it actually compiles fine... So ResConv needs a few more things defined in the .grc files we forgot about.

First of all let me say that Stefan's solution is almost entirely correct. Nice work!
So ResConv needs to know the WIN_LANGUAGE_ID which is defined in GSLocalization.h, depending on your language selection - this is why you need the INT__APP define (but if you're building a localized version for say German, then you'd need GER__APP instead).
Now when ResConv compiles the 'VERS' resource it expects two strings describing your Add-On to be already defined - these are INTERNAL_NAME (The name of the Add-On) and ORIGINAL_NAME (the filename). That's Stefan's solution so far.

What more could be done? Well, since these strings and the language setting is actually a localizable resource, these should go into the localized .grc file. What's even more is that some strings in the 'VERS' resource could also be localized -> move those also.

So the result should look something like this (the '@' character at the beginning of the lines tells ResConv to include the whole line verbatim):
AddOn.grc should contain:
@#define	INT__APP
@#define	INTERNAL_NAME	"Hello World"
@#define	ORIGINAL_NAME	"HelloWorld.apx"
@
@#define	COMPANY_STR		"Some Company"
@#define	COPYRIGHT_STR	"Copyright © Some Company 2004"
@#define	FILEDESC_STR	"API DevKit Sample"
@
AddOnFix.grc should contain:
@#include "GSLocalization.h"
@

/* Version resource - uses strings defined in the localizable resource file */
'VERS' {
	COMPANY_STR
	COPYRIGHT_STR
	FILEDESC_STR
	1.00
	1.00
	"ArchiCAD"
	8.1
}
Hope that clears up the problem...

Regards:
Andras Babos.
Anonymous
Not applicable
Akos wrote:
The behavior of ACAPI_WriteReport depends on the "Write Report" switch in Imaging and Calculation preferences.
I tried switching it on and off, but no message box appeared. I then tried switching off the "Interrupt with error messages" switch, and suddenly I've got greetings both in the message box and the report window

Then Akos wrote:
If you want an alert box which appears in every case, use DGAlert, DGResAlert, or DGResAlertParam.
I would love to use them, but again I'm struggling to figure out what is the bare essentials here. When I study the example Add Ons it's hard, for me at least [newbie], to grasp what it is I need for this simple task and what do I need for another one...
How would you extend helloworld to use the DGAlerts?

--
Regards,
Tor Jørgen
Ralph Wessel
Mentor
vannassen wrote:
Then Akos wrote:
If you want an alert box which appears in every case, use DGAlert, DGResAlert, or DGResAlertParam.
I would love to use them, but again I'm struggling to figure out what is the bare essentials here.
First up, use the documentation provided with the developer kit - it has a very good description of these functions. You really must familiarise yourself with these documents, because you will otherwise have to ask for help at every stage. You can find the documentation on DGAlert in the Dev Kit at <Documentation/HTML/DialogManager/DialogManager.html>. In this document, click on the link labelled 'Function list' and then on the function 'DGAlert'. At the top of the page describing DGAlert, you will also see a link to 'alert', which has a very good description of the alert types. The path to this document is: <Documentation/HTML/DialogManager/DGHtmlLibrary/Alerts.html>

For the 'Hello World' exercise, you could insert the following:
DGAlert(DG_INFORMATION, "Hello Alert", "Hello World", 0, "OK", 0, 0);
This will display a standard message alert titled "Hello Alert" and displaying the message "Hello World" with a single "OK" button. You will ultimately not want to hard-code your strings as shown above. Put them in your add-ons resources instead, i.e. into a .grc file, and retrieve them with 'ACAPI_Resource_GetLocStr'
Ralph Wessel BArch
Software Engineer Speckle Systems
Anonymous
Not applicable
Thanks Ralph,
for your codesnippet to show the use of DGAlert. I tried it, and after including DG.h in the cpp file, and including DGImp.lib in the project, it worked perfect 😄

I am, really, trying to familiarize myself with the documentation. I guess my real problem is that I haven't done this type of programming before, and that the first thing is just as new and overwhelming as the next. And I agree, there is a lot of documentation to all the pieces, again what I'm missing is the big picture - which I'm sure will get clearer as I work on... (maybe it's my preference for reading drawings and pictures over text in a foreign language 😉

[so for now I'll just leave the fact that I couldn't get the icon thing from LubosC to work...]

In absence of a stack of books and tutorials on the subject, this forum is really great, and I'm extremely happy for all the response my 'Hello World' thread has gotten. 😄

I'll soon be back with more questions concerning my actual project which includes the task of building lines, arcs and fills - maybe even meshes describing the terrain - from the information stored in a textfile (sosi) like this
.HODE 0:                                       !
..TEGNSETT DOSN8                               !
..TRANSPAR                                     !
...KOORDSYS 41                                 !
...ORIGO-Nù 0 0                                !
...ENHET 0.010                                 !
..OMRèDE                                       !
...MIN-Nù  6526954   311542                    !
...MAX-Nù  6527158   311652                    !
..SOSI-VERSJON 3.1                             !
..SOSI-NIVè 4                                  !
.BUE 1:
..OBJTYPE SenterlinjeVeg
..RADIUS 44.565
..LTEMA 7001
..NùH
652701270 31156088 0
652700509 31157665 0
.LINJE 2:
..OBJTYPE SenterlinjeVeg
..LTEMA 7001
..NùH
652700509 31157665 0
652697796 31161213 0

... and so on...
which is a way of spesifying the head 0 (general info), arc 1, line 2, coordinates, what layer it should be put on, and so on. I'm thinking that maybe this should have been a xml file, and I have this problem with the characterset, as you see, but as it's the norwegian department in charge of mapping who's in charge, I shouldn't hope for too much...

- any suggestions, fell free 🙂
--
Regards,
Tor Jørgen
Ralph Wessel
Mentor
Tor wrote:
I am, really, trying to familiarize myself with the documentation. I guess my real problem is that I haven't done this type of programming before, and that the first thing is just as new and overwhelming as the next.
That's a common problem with any API - there usually isn't a big picture because of the diverse uses it could be put to. Although painful to start with, in the long run you will be better off for absorbing as much of the documentation as possible. Don't try to memorise it all - learn enough to know what's there, and then you can refer back to it when you need the implementation details.
Tor wrote:
so for now I'll just leave the fact that I couldn't get the icon thing from LubosC to work...
I don't think it will work on a Mac - the last time I looked at that, it was a Windows-only feature. Someone correct me if that has changed.
BTW - don't forget my comments about the compiler settings for the MSL libraries. Simply using the default libraries would be a Bad Thing.
Ralph Wessel BArch
Software Engineer Speckle Systems
Anonymous
Not applicable
I now feel that I have taken a giant leap, I'm even able to read a file and display it in the alert... But then I get some new questions, maybe it's really a strictly c++ question, but I'll try posting it anyway...

What I'm trying to do is reading the sosi-file I showed a bit of in my last posting, and build some ArchiCAD-stuff from it, what are the recommended classes to use for that kind of thing - I need really one line at the time, and then build something from that line. And I think I should do this recursivly...

I'm also concerned with stucture; should I keep all the routines for handling the reading of the file in one cpp-file, and than the buildingroutines in another cpp-file?

--
Regards,
Tor Jørgen
Ralph Wessel
Mentor
Tor wrote:
What I'm trying to do is reading the sosi-file I showed a bit of in my last posting, and build some ArchiCAD-stuff from it
Have you searched for any existing resources for reading this file format? There may be code/libraries available, especially if this format is in the public domain, i.e. it is not a proprietry format. If you can find anything, it may be a starting point for an ArchiCAD-based reader.
Tor wrote:
what are the recommended classes to use for that kind of thing ...
I'm also concerned with stucture; should I keep all the routines for handling the reading of the file in one cpp-file, and than the buildingroutines in another cpp-file?
These questions are too open-ended - you need to work through the problem some more. Look for existing resources which might relate to this problem. Do some research. Write some psuedo-code. Break the problem into smaller modules, and then progressively work up the detail for each of them. Then some answers to your questions might start to become apparent and you can come back with more detailed questions.
Ralph Wessel BArch
Software Engineer Speckle Systems
Anonymous
Not applicable
Ralph wrote:
You can debug, set break points, inspect variable/memory, etc. You need to set ArchiCAD as the target executable in your runtime settings so that it is launched when you 'Run' your add-on, and the build settings need to be appropriate for debugging, e.g. low optimisation. I could be more specific if you can provide a brief description of the platform you are using, e.g. OS, IDE/compiler, AC version, etc.

I'm still wondering how this works...

I've set the working ArchiCAD application as target under 'Runtime settings'. Usually I just click 'Compile' and then 'Make' and then use 'Add-On manager' in ArchiCAD to get the Add-On. That works, but then I can't see any debug info anywhere. I've tried choosing 'Debug' instead, but then everything (CodeWarrior) freezes...

I'm using CodeWarrior 9 IDE 5.5, ArchiCAD 8.1.0 v1 NOR (1410), OSX 10.3 on a twin G5 1.8.

What needs to be done?
--
Regards,
Tor Jørgen
Ralph Wessel
Mentor
Tor wrote:
Ralph wrote:
You can debug, set break points, inspect variable/memory, etc. You need to set ArchiCAD as the target executable in your runtime settings

I've set the working ArchiCAD application as target under 'Runtime settings'. Usually I just click 'Compile' and then 'Make' and then use 'Add-On manager' in ArchiCAD to get the Add-On. That works, but then I can't see any debug info anywhere. I've tried choosing 'Debug' instead, but then everything (CodeWarrior) freezes...
First check that you have a Debug target in your project. If you used the 'Graphisoft Add-on' template when you created the project, you should have two targets: Final and Debug. You want to use the Debug target. All the files should be set to compile for debugging (in the debug column in the main project window). Optimisation should be turned off. Breakpoints can be set by clicking in the column to the far left of the relevant line of code.

Quit from ArchiCAD before doing a 'Make' or using the 'Debug' command. To start a debugging session, you should use the 'Debug' command. CodeWarrior should launch ArchiCAD and display the Debug window and log. All you need to do is activate the functionality in ArchiCAD which will run to the breakpoint, e.g. selecting your menu item.

The CodeWarrior Debug window will come to the front when it hits the breakpoint, and will display the context and position of the breakpoint. The list to the upper left shows the stack traceback (a kind of roadmap of key steps that led to this point), and relevant variables are listed to the upper right. You can do all the normal debug things, e.g. view (and often edit) variable values, step through line by line, continue execution, or kill the process. Note that killing the process means ending the ArchiCAD session, i.e. it will be as if ArchiCAD unexpectedly quit.
Ralph Wessel BArch
Software Engineer Speckle Systems
Anonymous
Not applicable
I've used the Graphisoft-Add-On template, and I'm using the debug target, and I've turned off optimization.

Ralph wrote:
All the files should be set to compile for debugging (in the debug column in the main project window).
I'm not quite shure what you mean, but I've clicked the little dot under the little green bug in the main project window.

Now I can start ArchiCAD by clicking Run, but when I click Debug it says 'loading debugging data for target "add-on debug', but nothing happens...

--
Regards,
Tor Jørgen