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

Modal to Modeless

Anonymous
Not applicable
Hi developers,

I have alredy made an aplicattion who works properly with a Modal Dialog. Now, i would like to change this modal dialog into a Modeless one. But i have found some problems, due to when i run the API i can not interact with the Dialog and in few seconds, the application closes and error report starts. I have read the Developer's Manual and i can not see the problem. This is my function:


filNum = ACAPI_UseOwnResModule (); // Set own resource file the active one
//isOK = (DGModalDialog(CalcEnerMin_GDLGID, CalcEnerMinDlgCallBack,0) == DG_OK);
DGModelessInit(CalcEnerMin_GDLGID, CalcEnerMinDlgCallBack,0,1);
ACAPI_ResetResModule (filNum);


And here the GRC code:

'GDLG' 32530 Modeless 0 0 570 620 "Modeless"


I have also read something about the function "DGModelessHandler" but i am not sure if i should use it or not and how it works.

I will be really grateful if somebody could help me.
16 REPLIES 16
Ralph Wessel
Mentor
frankito5 wrote:
I have alredy made an aplicattion who works properly with a Modal Dialog. Now, i would like to change this modal dialog into a Modeless one. But i have found some problems, due to when i run the API i can not interact with the Dialog and in few seconds, the application closes and error report starts.
Try making the dialog a palette rather than a modeless dialog - I believe there may still be underlying problems registering a modeless dialog correctly from the API.

Did you find the documentation for DGModelessInit? That explains pretty much everything you need to know. Also, take a look at DGShowModelessDialog
Ralph Wessel BArch
Software Engineer Speckle Systems
Anonymous
Not applicable
The first i did was read the manual. But i have tried in some ways but without success, that's why i'm asking to expert developers! I have tested it with two different options:

static void Prueba_Modeless (void){

GSResModule filNum;
short modelessID;

filNum = ACAPI_UseOwnResModule (); // Set own resource file the active one
//modelessID = DGModelessInit(Modeless_GDLGID, ModelessDlgCallBack, 0, 0);
modelessID = DGCreateBlankModelessDialog(320,250,DG_DLG_NOGROW,DG_DLG_CLOSE,DG_DLG_MINIMIZE,DG_DLG_MAXIMIZE,DG_DLG_NOCAPTION,DG_DLG_THICKFRAME,ModelessDlgCallBack,0);

if(modelessID != 0){
DGBeginProcessEvents(modelessID);
DGShowModelessDialog(modelessID, DG_DF_FIRST);
}

ACAPI_ResetResModule (filNum);

return;
}

With the red one i have compiling problems(i can not understand it). The same if i try with the Palette instead of Modeless as u suggested me:

DG_Test.obj : error LNK2019: símbolo externo __imp_DGCreateBlankModelessDialog sin resolver al que se hace referencia en la función "void __cdecl Prueba_Modeless(void)" (?Prueba_Modeless@@YAXXZ)

With the green one, the Dialog appears but i cant operate or move it and in few seconds, bug problems dialog appear and archiCAD closes.

Am i forgetting something ??
Ralph Wessel
Mentor
frankito5 wrote:
With the green one, the Dialog appears but i cant operate or move it and in few seconds, bug problems dialog appear and archiCAD closes.
Have you determined where the crash is occurring (e.g. with the debugger)?
Ralph Wessel BArch
Software Engineer Speckle Systems
Anonymous
Not applicable
Yes, but i don't know where exaclty is the problem. Anyway, i have tried in an API developement Kit example(DG_Test) just changing the Modeless rather than the Modal dialog and the same problem happen.

I have printed some values to know where the program crashes but everything seems good. I show it:

static void Prueba_Modeless (void){

GSResModule filNum;
short modelessID;

ofstream mod("modeless.txt");

filNum = ACAPI_UseOwnResModule (); // Set own resource file the active one

modelessID = DGModelessInit(Modeless_GDLGID, ModelessDlgCallBack, 0, 0);
mod << "Create Dialog " << modelessID << endl;

//modelessID = DGCreateBlankModelessDialog(320,250,DG_DLG_NOGROW,DG_DLG_CLOSE,DG_DLG_MINIMIZE,DG_DLG_MAXIMIZE,DG_DLG_NOCAPTION,DG_DLG_THICKFRAME,ModelessDlgCallBack,0);

if(modelessID != 0){
DGBeginProcessEvents(modelessID);
mod << "Begin process" << endl;
DGShowModelessDialog(modelessID, DG_DF_FIRST);
mod << "Show Dialog" << endl;
}

ACAPI_ResetResModule (filNum);

mod << "Reset Module" << endl;

return;
}

Here, all the sentences are written in the .TXT file and also the value of the Dialog(32540 in this case). It means, the Dialog is created without any problem.


static short DGCALLBACK ModelessDlgCallBack (short message, short dialId, short itemId,
DGUserData /*userData*/, DGMessageData /*msgData*/){

short alto=0, ancho=0;
itemId=itemId;
ofstream mod2("modelessCall.txt");

mod2 << "START" << endl;

switch (message) {
case DG_MSG_INIT:
mod2 << "INIT" << endl;
DGGetDialogSize (dialId, DG_ORIGFRAME, &ancho, &alto);
//void DGSetDialogSize (short dialId,short rectType,short hSize,short vSize,short fixPoint,bool keepOld);
//DGSetDialogSize (dialId, DG_CLIENT, ancho, alto, DG_TOPLEFT, true);
break;
case DG_MSG_CLOSE:
mod2 << "CLOSE" << endl;
break;
case DG_MSG_CHANGE:
mod2 << "CHANGE" << endl;
break;
case DG_MSG_CLICK:
mod2 << "CLICK" << endl;
break;
}

mod2 << "EXIT" << endl;

return(0);
}


Here, START and EXIT are written. It's supossed INIT has to appear also, but i think it does not because of the callback behaviour. But i have tried to comment 'DGSetDialogSize ' and the Dialog really dont change the size so it get into INIT case.

I think i am forgetting something in the Callback, but i am not sure. Could be something related with the 'DGModelessHandler'? It converts the system messages in DG messages but i don't know it is necessary. Some suggestions? I am blocked and i do not know how to continue

THANKS
Ralph Wessel
Mentor
frankito5 wrote:
I think i am forgetting something in the Callback, but i am not sure. Could be something related with the 'DGModelessHandler'? It converts the system messages in DG messages but i don't know it is necessary. Some suggestions? I am blocked and i do not know how to continue
Sorry, I can't pinpoint what's going wrong here. There are some redundancies in your code, but they wouldn't cause a crash, e.g. the following does nothing:
itemId=itemId;
...and it is unnecessary to call DGBeginProcessEvents because DGModelessInit does this for you.

I think it is very important to determine the point where the add-on crashes - it may have nothing to do with the dialog. The stack trace could provide important clues to the reason for the failure. I'm surprised the debugger isn't trapping the crash - are you sure you're running the debug version and have at least one breakpoint set? If you're debugging with Visual Studio, it might also be useful to turn on all the runtime checks too.
Ralph Wessel BArch
Software Engineer Speckle Systems
Anonymous
Not applicable
Ralph wrote:
frankito5 wrote:

I think it is very important to determine the point where the add-on crashes - it may have nothing to do with the dialog. The stack trace could provide important clues to the reason for the failure. I'm surprised the debugger isn't trapping the crash - are you sure you're running the debug version and have at least one breakpoint set? If you're debugging with Visual Studio, it might also be useful to turn on all the runtime checks too.

I will try to find it, but i'm sure is something about dialog modes, because the same add-on works properly with Modal Dialog. If you have time, check it in the API Development Kit 14 in the DG_TEST example. Try to change one Modal Dialog to a Modeless and you will see the same problem(I have alredy checked it). That's why i can't understand the problem...
Anonymous
Not applicable
When im debugging, the report gives the following information:

Exception code: C0000005 ACCESS_VIOLATION writing location: 0000000180004860
Primera excepción en 0x76fccb23 en ArchiCAD.exe: 0xC0000005: Infracción de acceso al leer la ubicación 0x0000000180004860.
Fault address: 0000000180004860 (ILLEGAL)

I can't see info with the breakpoints because when y press f5, arhiCAD runs and when i open de addON from the Menu, the dialog appears and in few seconds archiCAD is closed and also de debugger mode.

Now, could you give me more information about possible solutions??
Ralph Wessel
Mentor
frankito5 wrote:
When im debugging, the report gives the following information:[]
Now, could you give me more information about possible solutions??
What about the stack trace? This will tell you where the crash occurred and - more importantly - the call sequence leading up to it.

Just to confirm - have you changed the dialog resources in these tests to identify it as a palette rather than a modeless dialog?
Ralph Wessel BArch
Software Engineer Speckle Systems
Anonymous
Not applicable
What about the stack trace? This will tell you where the crash occurred and - more importantly - the call sequence leading up to it.
Call stack:

0x0000000180004870!ArchiCAD.exe + -2147465104
0x000000005FCA6ADB!DG.dll + 748251 (DGGetDialogResourceModule + 923 bytes)
0x000000005FC8DBF9!DG.dll + 646137 (DGEndProcessEvents + 3113 bytes)
0x000000005FC8FECD!DG.dll + 655053 (DGEnableMessage + 2345 bytes)
0x000000005FC90FEB!DG.dll + 659435 (DGBeginProcessEvents + 4347 bytes)
0x000000005FCC7016!DG.dll + 880662 (DGSetModelessDialogState + 554 bytes)
0x0000000077368971!USER32.dll + 100721 (GetWindowDC + 129 bytes)
0x00000000773672CB!USER32.dll + 94923 (SetWindowTextW + 631 bytes)
0x0000000077366829!USER32.dll + 92201 (IsDialogMessageW + 361 bytes)
0x00000000776B1225!ntdll.dll + 332325 (KiUserCallbackDispatcher + 31 bytes)
0x000000007736685A!USER32.dll + 92250 (IsDialogMessageW + 410 bytes)
0x0000000077363838!USER32.dll + 79928 (GetWindowLongPtrA + 120 bytes)
0x0000000077366BAD!USER32.dll + 93101 (SendMessageW + 93 bytes)
0x000007FEFC31645C!UxTheme.dll + 25692 (DrawThemeParentBackgroundEx + 340 bytes)
0x000007FEFC762D80!COMCTL32.dll + 667008
0x00000000127D5740!UNKNOWN_MODULE
0xFFFFFFFFF7011F90!UNKNOWN_MODULE
0x0000000000000001!ArchiCAD.exe + 1
0x000000000012EED8!UNKNOWN_MODULE
0x000000000012EEF8!UNKNOWN_MODULE
0x00000000026FE270!UNKNOWN_MODULE
0x000000000012EE01!UNKNOWN_MODULE
0x0000000100000001!ArchiCAD.exe + 1


Just to confirm - have you changed the dialog resources in these tests to identify it as a palette rather than a modeless dialog?
'GDLG' 32540 Modeless 0 0 320 250 "Prueba" {

/*1*/ Button 190 255 80 20 LargePlain "Aceptar"

}

'DLGH' 32540 DLG_32540_Modeless {

1 "" Button_0

}