October 30, 2025, 02:40:24 AM

News:

IWBasic runs in Windows 11!


Calling Windows From DLL's (Plugins)

Started by Zen, July 10, 2006, 09:10:05 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Zen

July 10, 2006, 09:10:05 AM Last Edit: July 10, 2006, 09:26:07 AM by Lewis
Ok i used to do this a lot with IBasic and i seem to be having some problems here...

I have create a plugin manager class for CCL and a Plugin class from which the plugins will based from. When the plugin manager searches the plugins directory it then loads the dll file, finds the "InitCCLPlugin" subroutine and passes a pointer to the PluginManager class, from which the InitCCLPlugin routine can then call the RegisterPlugin method to register however many plugins there are in that dll file.

After all the plugins are loaded, you can then select a plugin to run, by calling the plugins Run() method, in a simple plugin i just made it call the MessageBox function and all was ok, now that i have create a window class within the plugin, as soon as it is displayed it is crashing instantly, and not just the plugin, it also crashed the parent application too.

Here is the code for the plugin DLL...

/***************************/
/*** Declare DLL Exports ***/
/***************************/

export InitCCLPlugin;

/**************************************/
/*** Sample Window Class Definition ***/
/**************************************/

class TestWindow : CWindow {

declare OnClose(),int;
declare OnCreate(),int;

}

TestWindow :: OnClose(),int {

Destroy();

return true;

}

TestWindow :: OnCreate(),int {

CenterWindow();

}

/******************************/
/*** Test Plugin Definition ***/
/******************************/

class TestPlugin : CPlugin {

// declare TestPlugin();
// declare _TestPlugin();

declare Initialize(),int;
declare Run(),int;

TestWindow m_Main;

}

/************************************/
/*** Method To Initialize Plugins ***/
/************************************/

sub InitCCLPlugin(CPluginManager *PluginManager) {

PluginInfoStruct Plugin1Info;
TestPlugin Plugin1;

Plugin1Info.Plugin = Plugin1;
Plugin1Info.Name = "Test Plugin";
Plugin1Info.Author = "Lewis Lambert";
Plugin1Info.MajorVersion = 1;
Plugin1Info.MinorVersion = 0;
Plugin1Info.SiteLink = "http://www.google.com/";
Plugin1Info.UpdateLink = "http://www.google.com/";

PluginManager->RegisterPlugin(Plugin1Info);

return;

}

/*************************/
/*** Class Constructor ***/
/*************************/
/*
TestPlugin :: TestPlugin() {

return;

}
*/
/***************************/
/*** Class Deconstructor ***/
/***************************/
/*
TestPlugin :: _TestPlugin() {

return;

}
*/
/***************************************/
/*** Method To Initialize The Plugin ***/
/***************************************/

TestPlugin :: Initialize(),int {

return true;

}

/********************************************/
/*** Method Called When The Plugin Is Run ***/
/********************************************/

TestPlugin :: Run(),int {

// m_Main.Create(10,10,640,480,AWS_CAPTION|AWS_SYSMENU|AWS_BORDER|AWS_VISIBLE,0,"Test Plugin",null);

MessageBox(0,"Hello World","Plugin");

/*
do {

wait();

} until(m_Main.m_Hwnd = 0);
*/
return 0;

}


Obviously you can see where i have commented bits of the code out in order to try and narrow the problem down. No joy!

If anyone can help me out on this one it would be great.

Lewis

Ionic Wind Support Team

It's usually a bad idea to have two message loops in an application.  Having one in your main program is sufficent enough to handle all windows created by DLL's.

One thing I don't see is where you creating an instance of the 'testplugin' class?
Ionic Wind Support Team

Zen

Its in the InitCCLPlugin subroutine. I have tried it in and out of the the subroutine and i get crashes either way. But if i dont do the message loop then how will my window recieve its messages? Or does the one wait() routine handle all windows created within aurora?

Lewis

Ionic Wind Support Team

Your creating the class as a local variable.  When the InitCCLPlugin subroutine returns all local variables no longer exist.  So your plugin1 class would be deconstructed and removed from the stack.

Yes one WAIT() loop anywhere in your applications will handle all windows/dialogs/controls.

Anyway I normally handle a window in a DLL dynamically.  ClassMaker and the MenuEditor are both DLL's that the IDE uses.  This is the code used to show the class maker dialog.  You can apply the same technique for a window.  The message loop of the IDE handles processing the messages for the dialog.


int gShow;
CLassMaker *pDlg;
global sub ShowClassMaker(unsigned int hwnd)
{
if(gShow)
{
pDlg->ShowWindow(SWRESTORE);
BringWindowToTop(pDlg->m_hWnd);

return 0;
}
pDlg = new(ClassMaker,1);
pDlg->Create(0,0,530,380,0x80CA0080,0,"Q&D Class Maker",0);
pDlg->SetDefaultFont("Verdana",8); //sets the default font for all of the controls
pDlg->AddControl(CTLISTBOX,"ListBox1",24,41,189,62,0x50800140|AWS_VSCROLL|ALBS_NOTIFY,0x200,IDC_CLASSLIST);
pDlg->AddControl(CTLISTBOX,"ListBox2",24,122,189,190,0x5080014A|AWS_VSCROLL|AWS_HSCROLL|ALBS_NOTIFY,0x200,IDC_METHODLIST);
pDlg->AddControl(CTSTATIC,"Available Classes (Double Click)",26,23,199,18,0x5000010B,0x0,STATIC_14);
pDlg->AddControl(CTSTATIC,"Virtual Methods",26,107,90,18,0x5000010B,0x0,STATIC_4);
pDlg->AddControl(CTSTATIC,"Derived Class Name",313,69,116,17,0x5000010B,0x0,STATIC_5);
pDlg->AddControl(CTEDIT,"",312,83,139,21,0x50800000,0x200,IDC_DERIVEDNAME);
pDlg->AddControl(CTLISTBOX,"ListBox3",311,122,189,190,0x5080014A|AWS_VSCROLL,0x200,IDC_DERIVEDLIST);
pDlg->AddControl(CTBUTTON,">>",242,160,47,19,0x5000000B,0x0,IDC_ADD);
pDlg->AddControl(CTBUTTON,"<<",242,199,47,19,0x5000000B,0x0,IDC_REMOVE);
pDlg->AddControl(CTBUTTON,"Close",165,333,70,20,0x5000000B,0x0,IDC_CLOSE);
pDlg->AddControl(CTBUTTON,"Generate",295,333,70,20,0x5000000B,0x0,IDC_GENERATE);
pDlg->AddControl(CTSTATIC,"Base Class Name",314,33,101,16,0x5000010B,0x0,15);
pDlg->AddControl(CTEDIT,"",312,48,139,21,0x50800000,0x200,IDC_BASENAME);
gShow = true;
pDlg->ShowDialog();
return 0;
}

......

ClassMaker::OnClose(),int
{
gShow = false;
pDlg = NULL;
CloseDialog(0);
delete this;
return true;
}

Ionic Wind Support Team

Zen

Ahh, well i did try it outside of the subroutine but im not sure why it wasnt working still. But i will try making it with the new statement and see what that does. Also, could it have something to do with the base address of the dll's? I know that was an issue with IBasic when i was doing plugin systems.

Lewis

Ionic Wind Support Team

Global classes are not constructed. 

base addresses are important if you want you dll's to work in al systems.  Windows 9x doesn't rebase DLL's when loading so if you try and load two dll's at the same base address the program will crash.  Usually in kernel32.

Ionic Wind Support Team

Zen

Well using the new statement seemed to solve that one just fine thanks Paul. I know the issue of using windows in IBasic never got sorted after all mine, yours and seans efforts. But im glad it works fine here.

Thanks a million Paul.
Lewis

Ionic Wind Support Team

Quote
I know the issue of using windows in IBasic never got sorted after all mine, yours and seans efforts.

Too many global dependancies in IBasic for the window to work in a DLL.

Aurora uses a class structure for a window so there isn't any global variable collisions.
Ionic Wind Support Team

Zen

Ok ive got another little problem, i think it is related to this so ill keep it in this thread.

I have an MDI frame which is loading the plugins, one of the plugins is creating a mdi child window and it works ok apart from if i maximize the child window then close it, for some reason the client area goes as it would normally but the min, max and close buttons remain on the menu bar aswell as the little icon the window puts there when its maximized. Am i doing something wrong?

Lewis

Ionic Wind Support Team

I'll assume your deriving from MDIChildWnd correct?

What does your OnClose handler for the child window look like?
Ionic Wind Support Team

Zen

Yes i am deriving from MDIChildWnd, my OnClose handler looks like this...


TestWindow :: OnClose(),int {

Destroy();

return true;

}


Lewis