Author Topic: Win32 dialogs in ARX  (Read 10876 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Win32 dialogs in ARX
« Reply #15 on: February 08, 2006, 12:00:04 AM »
In AC2006 :
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

MickD

  • Gator
  • Posts: 3242
  • !false...it's funny 'cause it's true!
Re: Win32 dialogs in ARX
« Reply #16 on: February 08, 2006, 12:14:54 AM »
Thanks Kerry, hadn't tried it in 2005/6, seems to work ok. :)
Although I could probably do without modeless dialogs for my personal needs, this is presenting quite a challange that is worth persuing as it will be a good learning tool for using win32 and all its power....mmwaAHAHAHa! :D
A programmer's wife tells him, "Run to the store and pick up a loaf of bread. If they have eggs, get a dozen."

The programmer comes home with 12 loaves of bread.

LE

  • Guest
Re: Win32 dialogs in ARX
« Reply #17 on: February 08, 2006, 12:28:34 PM »
I see, that the samples are using the functions GlobalXXX for memory management... I remember when I wrote my ClipBoard project, that they recommended to use "Heap Functions"

Quote
Note  The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

It will be [I think simple to just change] GlobalXXX to HeapXXX

If the above does not make any sense... please ignored...  :ugly:

MickD

  • Gator
  • Posts: 3242
  • !false...it's funny 'cause it's true!
Re: Win32 dialogs in ARX
« Reply #18 on: February 08, 2006, 05:48:01 PM »
Luis, it was just a copy and paste of something I knew worked to get something going, this would definitely not be production code ;)

Try just returning TRUE for the WM_ACAD_KEEPFOCUS message.

Chuck, you're right, it should work after thinking about it and looking at the mfc samples in the sdk (where they simply return TRUE). The message map simply maps your functions to windows messages anyway so there is no difference really. Must be missing something simple here...
A programmer's wife tells him, "Run to the store and pick up a loaf of bread. If they have eggs, get a dozen."

The programmer comes home with 12 loaves of bread.

cornbread

  • Guest
Re: Win32 dialogs in ARX
« Reply #19 on: February 13, 2006, 12:43:43 PM »
If you ever figure out what it is let us know. I always process the WM_ACAD_KEEPFOCUS message by returning TRUE and it seems to have no effect on my modeless dialogs. I don't work much with Acad but I do rember battling with that for a while and then giving up because I could never get it to keep the focus even following the API and processing that message. The message does get sent you can watch it in a symbol debugger but it's almost like Acad ignores it. I could never find what I was missing to make it truly modeless.

MickD

  • Gator
  • Posts: 3242
  • !false...it's funny 'cause it's true!
Re: Win32 dialogs in ARX
« Reply #20 on: February 13, 2006, 03:59:15 PM »
Yep, I've just about given up also and I was clearly catching the message too. I really thought that MFC just mapped the messages to functions to handle them (and I still do), maybe it's something to do with the MFC dialog class that you derive your dialogs from that has some magic??
Maybe it might be a case of hooking into the main window proc and catching/handling it somehow?
A programmer's wife tells him, "Run to the store and pick up a loaf of bread. If they have eggs, get a dozen."

The programmer comes home with 12 loaves of bread.

cornbread

  • Guest
Re: Win32 dialogs in ARX
« Reply #21 on: February 14, 2006, 01:21:34 PM »
Cr@p in thinking about it I figured out what was wrong. Set the style of the dialog to overlapped either via a WS_OVERLAPPED if you are doing it on the fly or if you are in the Visual Studio resource editor it should have that as one of the styles. By default I think it's popup which will loose focus as soon as it appears because it's the style modal dialoges use not modeless ones. That and handle the WM_ACAD_KEEPFOCUS message by returning true and it should fix the problem.

MickD

  • Gator
  • Posts: 3242
  • !false...it's funny 'cause it's true!
Re: Win32 dialogs in ARX
« Reply #22 on: February 14, 2006, 03:54:01 PM »
Damn! so simple!
I tried every other setting you know except overlapped as I've read that overlapped windows are not recomended for dialogs.
I just gave myself a crash course on message hooks and found a few snippets I was going to implement today, if any one wants I'll post the links but hooks are not the best solution really and they use more resources to maintain the hook.
Thanks CB, that saved me a few hours.

I'll post a simple cpp framework skeleton of a modal an modeless dialogs after I do some code cleaning and testing.
A programmer's wife tells him, "Run to the store and pick up a loaf of bread. If they have eggs, get a dozen."

The programmer comes home with 12 loaves of bread.

cornbread

  • Guest
Re: Win32 dialogs in ARX
« Reply #23 on: February 14, 2006, 04:16:13 PM »
Do you want my code for getting the handle of the session of Acad that your Arx is loaded into so you don't have to use adsw_acadMainWnd? adsw_acadMainWnd uses MFC that is why I ask.

MickD

  • Gator
  • Posts: 3242
  • !false...it's funny 'cause it's true!
Re: Win32 dialogs in ARX
« Reply #24 on: February 14, 2006, 04:24:10 PM »
Yes please, for completeness.
A programmer's wife tells him, "Run to the store and pick up a loaf of bread. If they have eggs, get a dozen."

The programmer comes home with 12 loaves of bread.

cornbread

  • Guest
Re: Win32 dialogs in ARX
« Reply #25 on: February 14, 2006, 04:39:31 PM »
The class:
Code: [Select]
#ifndef _MAINWIN_H_INCLUDED
#define _MAINWIN_H_INCLUDED

#include "windows.h"
#include "Psapi.h"

class MainWin{
public:
MainWin() : hWnd(NULL), procId(NULL){}
~MainWin(){}

HWND getMainWindowHandle(){
hWnd = NULL; procId = NULL;
procId = GetCurrentProcessId();
EnumWindows(matchProcessIdToWindow, (LPARAM)this);
return hWnd;
}

private:
DWORD procId;
HWND hWnd;
static BOOL CALLBACK matchProcessIdToWindow(HWND hWnd, LPARAM lParam) {
MainWin *mnw = reinterpret_cast<MainWin*>(lParam);
if ((GetWindowLong(hWnd,GWL_STYLE) & WS_VISIBLE)){
DWORD pidwin;
GetWindowThreadProcessId(hWnd, &pidwin);
if(pidwin==mnw->procId) {
mnw->hWnd = hWnd;
return FALSE;
}
}
return TRUE;
}
};


#endif

an example of it's use:
Code: [Select]
        MainWin mwn;

HWND AcadHwnd = mwn.getMainWindowHandle();

if(AcadHwnd){
HWND dlgHwnd = CreateDialog(_hdllInstance,
                  MAKEINTRESOURCE(IDD_DLG_WHATEVER),
                  AcadHwnd, (DLGPROC) DialogProc);
if(dlgHwnd){
ShowWindow(dlgHwnd, SW_SHOW);
}
}

MickD

  • Gator
  • Posts: 3242
  • !false...it's funny 'cause it's true!
Re: Win32 dialogs in ARX
« Reply #26 on: February 14, 2006, 06:03:37 PM »
Ok here it is, only a rough example to get you going. There is still a small issue when closing the modeless type that it sometimes minimises the main window which requires further investigation. I've also noticed this with the dialogs in AutoCAD sometimes, it can be anoying.

Remember to set your dialog window style to 'Overlapped' as cornbread pointed out above, not required for modal dilaogs but here I've used the same dialog class for both modal and modeless so it was changed from the standard Popup style.

the header file
Code: [Select]
/*----------------------------------------------------------------------------
 * Win32Dlg.h - by MickD Feb, 2006.
 * An *example only* of how to create and use win32 dialogs in ObjectARX.
 * Include this header in your acrxEntryPoint.cpp or similar file where
 * you will be creating your dialogs.
 *
 * Header file with the necessary items to create win32 api dialog boxes
 * Class - MainWin by Cornbread, get the handle(HWND)to the main application
 * window that is required when creating the dialogs.
 *
 * Window procedure prototypes - one for a modal dialog and one for a modeless
 * dialog. Add more for other dialogs as required.
 *---------------------------------------------------------------------------*/


#ifndef _WIN32DLG_H_INCLUDED
#define _WIN32DLG_H_INCLUDED

#include "windows.h" //required for ...windows!
#include "Psapi.h" //tools used for processes
#include "StdAfx.h" //also contains basic arx headers
#include "resource.h" //our dialog resources

//
class MainWin{
public:
MainWin() : hWnd(NULL), procId(NULL){}
~MainWin(){}

HWND getMainWindowHandle(){
hWnd = NULL; procId = NULL;
procId = GetCurrentProcessId();
EnumWindows(matchProcessIdToWindow, (LPARAM)this);
return hWnd;
}

private:
DWORD procId;
HWND hWnd;
static BOOL CALLBACK matchProcessIdToWindow(HWND hWnd, LPARAM lParam) {
MainWin *mnw = reinterpret_cast<MainWin*>(lParam);
if ((GetWindowLong(hWnd,GWL_STYLE) & WS_VISIBLE)){
DWORD pidwin;
GetWindowThreadProcessId(hWnd, &pidwin);
if(pidwin==mnw->procId) {
mnw->hWnd = hWnd;
return FALSE;
}
}
return TRUE;
}
};
//------------------< dialog proc definitions >---------------------------------------
BOOL CALLBACK modelessDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK modalDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);

#endif //_WIN32DLG_H_INCLUDED

the .cpp file

Code: [Select]
/*----------------------------------------------------------------------------
 * Win32Dlg.cpp - by MickD Feb, 2006.
 * An *example only* of how to create and use win32 dialogs in ObjectARX.
 * Include the Win32Dlg.h header in your acrxEntryPoint.cpp or similar file where
 * you will be creating your dialogs.
 *
 * Window procedure implementation - one for a modal dialog and one for
 * a modeless dialog. Add more for other dialogs as required.
 *---------------------------------------------------------------------------*/

#include "Win32Dlg.h"

//=============< Dialog window procedures >=========================================
BOOL CALLBACK modelessDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
int len = 0;
int i = 0;
HWND hEdit;
switch(Message)
{
case WM_INITDIALOG:
return TRUE;

case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
len = GetWindowTextLength(GetDlgItem(hwnd, IDC_EDIT1));
if(len > 0)
{
int i;
char* textbuf;

textbuf = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hwnd, IDC_EDIT1, textbuf, len + 1);

MessageBox(hwnd, textbuf, "Testing Modeless", MB_OK | MB_ICONEXCLAMATION);

GlobalFree((HANDLE)textbuf);
}
else
{
MessageBox(hwnd, "Nothing in Edit box to show???", "Testing Modeless",
MB_OK | MB_ICONEXCLAMATION);
}
break;
case IDCANCEL:
if(!DestroyWindow(hwnd))
MessageBox(NULL, "Failed to destroy window!", "KaBoom!",
MB_OK | MB_ICONEXCLAMATION);
break;
}
return TRUE;

case WM_ACAD_KEEPFOCUS:
return TRUE;
}
return FALSE;
};

BOOL CALLBACK modalDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
int len = 0;
switch(Message)
{
case WM_INITDIALOG:

return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
len = GetWindowTextLength(GetDlgItem(hwnd, IDC_EDIT1));
if(len > 0)
{
char* textbuf;

textbuf = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hwnd, IDC_EDIT1, textbuf, len + 1);

MessageBox(hwnd, textbuf, "Testing Modal", MB_OK | MB_ICONEXCLAMATION);

GlobalFree((HANDLE)textbuf);
len = 0;
}
else
{
MessageBox(hwnd, "Nothing in Edit box to show???", "Testing Modal",
MB_OK | MB_ICONEXCLAMATION);
}
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
len = GetWindowTextLength(GetDlgItem(hwnd, IDC_EDIT1));
if(len > 0)
{
char * textbuf;

textbuf = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hwnd, IDC_EDIT1, textbuf, len + 1);

acutPrintf("You type this into the text box: %s", textbuf);

GlobalFree((HANDLE)textbuf);
len = 0;
}
break;
}
break;
default:
return FALSE;
}
return TRUE;
};

the code to handle and create the dialogs in response to commands from the user.
Code: [Select]
// ----- DCSArxProject7.dlgmdl command
// Command for modal dialog test "DLGMDL"
static void DCSArxProject7dlgmdl(void)
{
MainWin mwn;
HWND hwnd = mwn.getMainWindowHandle();

int ret = DialogBox(_hdllInstance,/*our dll handle*/
MAKEINTRESOURCE(IDD_DIALOG1), hwnd, modalDlgProc);
if(ret == IDOK){
MessageBox(hwnd, "Dialog Button IDOK.", "Notice",
MB_OK | MB_ICONINFORMATION);
}
else if(ret == -1){
MessageBox(hwnd, "Dialog failed!", "Error",
MB_OK | MB_ICONINFORMATION);
}
}

// - DCSArxProject7.dlgmdls command (do not rename)
// Command for modeless dialog test "DLGMDLS"
static void DCSArxProject7dlgmdls(void)
{

MainWin mwn;
HWND hwnd = mwn.getMainWindowHandle();
HWND hModelessDlg = NULL;

// Add your code for command DCSArxProject7.dlgmdls here
if(_hModelessDlg==NULL)
{
hModelessDlg = CreateDialog(_hdllInstance, /*our dll handle*/
MAKEINTRESOURCE(IDD_DIALOG1),hwnd, (DLGPROC)modelessDlgProc);
if(_hModelessDlg != NULL)
{
ShowWindow(hModelessDlg, SW_SHOW);
}
else
{
MessageBox(hwnd, "CreateDialog returned NULL", "Warning!", 
MB_OK | MB_ICONINFORMATION);
}
}
else
{
ShowWindow(hModelessDlg, SW_SHOW);
}
}
A programmer's wife tells him, "Run to the store and pick up a loaf of bread. If they have eggs, get a dozen."

The programmer comes home with 12 loaves of bread.

MickD

  • Gator
  • Posts: 3242
  • !false...it's funny 'cause it's true!
Re: Win32 dialogs in ARX
« Reply #27 on: August 15, 2006, 05:38:24 PM »
I thought I'd post a sample of an actual dialog I'm using in a current project, all in win32.
I can only get int values from the edit box at the moment as that's all that's available in the api but I will be either catching the key events or sub classing the edit box window to handle alphabetical (unwanted) characters as soon as I get the functions and other things tidied up a bit.

The window procedure to handle windows messages (events) -
Code: [Select]
BOOL CALLBACK modifyDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
BOOL * xltd = FALSE;
// make these static to keep variable values between instances:
static int cutoffset = 0;
static int polycutoffset = 0;
static int polycutdepth = 1000;
static int drilldia = 22;
static int drilldepth = 50;
static int slotlength = 50;

switch(Message)
{
case WM_INITDIALOG:
// set the current values for the edit controls:
SetDlgItemInt(hwnd,IDC_EDIT_CUTOFF,cutoffset,TRUE);
SetDlgItemInt(hwnd,IDC_EDIT_POLYOFF,polycutoffset,TRUE);
SetDlgItemInt(hwnd,IDC_EDIT_POLYLEN,polycutdepth,TRUE);
SetDlgItemInt(hwnd,IDC_EDIT_DIA,drilldia,TRUE);
SetDlgItemInt(hwnd,IDC_EDIT_DEEP,drilldepth,TRUE);
SetDlgItemInt(hwnd,IDC_EDIT_SLOTL,slotlength,TRUE);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BTN_CUTL:
cutoffset = (int)GetDlgItemInt(hwnd,IDC_EDIT_CUTOFF,xltd,TRUE);
// call our cutting function:
//************************ here **********
break;
case IDC_BTN_CUTF:
cutoffset = (int)GetDlgItemInt(hwnd,IDC_EDIT_CUTOFF,xltd,TRUE);
// call our cut at face function:
//************************ here **********
break;
case IDC_BTN_POLYCUT:
polycutoffset = (int)GetDlgItemInt(hwnd,IDC_EDIT_POLYOFF,xltd,TRUE);
// call our poly cutting function:
//************************ here **********
break;
case IDC_BTN_SLOT:
drilldia = (int)GetDlgItemInt(hwnd,IDC_EDIT_DIA,xltd,TRUE);
drilldepth = (int)GetDlgItemInt(hwnd,IDC_EDIT_DEEP,xltd,TRUE);
slotlength = (int)GetDlgItemInt(hwnd,IDC_EDIT_SLOTL,xltd,TRUE);
// call our slotting function:
//************************ here **********
break;
case IDC_BTN_DRILL:
drilldia = (int)GetDlgItemInt(hwnd,IDC_EDIT_DIA,xltd,TRUE);
drilldepth = (int)GetDlgItemInt(hwnd,IDC_EDIT_DEEP,xltd,TRUE);
slotlength = (int)GetDlgItemInt(hwnd,IDC_EDIT_SLOTL,xltd,TRUE);
EndDialog(hwnd, IDC_BTN_DRILL);
// call our drilling function:
DrillHoles(drilldia,drilldepth);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
return TRUE;
};


and the image -
A programmer's wife tells him, "Run to the store and pick up a loaf of bread. If they have eggs, get a dozen."

The programmer comes home with 12 loaves of bread.

Draftek

  • Water Moccasin
  • Posts: 1501
Re: Win32 dialogs in ARX
« Reply #28 on: August 16, 2006, 07:50:54 AM »
Very nice and great topic.

Thanks
Soli Deo Gloria

MickD

  • Gator
  • Posts: 3242
  • !false...it's funny 'cause it's true!
Re: Win32 dialogs in ARX
« Reply #29 on: August 16, 2006, 06:26:03 PM »
The thing I like about win32 is you can always see exactly what's going on, MFC does it's best to hide it all with macro's like DDX (do data exchange)  and message maps etc which are basically doing exactly the same thing. It seems like a lot of work to make things easier, if you had to write MFC by hand (not use the class wizard) I reckon you would find it a real chore.
A programmer's wife tells him, "Run to the store and pick up a loaf of bread. If they have eggs, get a dozen."

The programmer comes home with 12 loaves of bread.