ChrisCrypto
Programmer
Me and my tutor have been racking our brains over this weird error all this and last week. Basically i have a program that links to DLLs that contains OpenGL code and then runs them (its an openGL Tutorial Program).
Everthing works apart from one (non-openGl) element the dll is meant to create a button on the form that can be used to pause the openGL. In my test program that i created it works perfectly however in my actuall program i have had an annoying problem with it. The dll creates the button on the form but when i click it, the button depresses but nothing happens, i know the function is assigned as a.) it works in my test program, b.) i force it to run at its creation using ->Click() which works. My tutor believes something has actually managed to damage the event message queue which would seem unlikely. He is an ex-industry programmer but he said this problem is so weird that i would actually need one of the programmers that designed Borland C++ builder. I am using v6 btw.
Everything is EXACTLY the same between the test prog and mine, they both loads up the DLL in the same way, run the same code everything is the same and from looking at it, it should WORK!
My problem took another wierd turn today, i changed my program again slightly. before my actual program loaded up the DLL while it was actually not visible whereas the test one was visible, so i changed my program to load the dll while visible and now the button doesnt show at all. I believe that maybe before the button somehow existed on the form virtually which is why it didnt run its event. I still dont understand why it shouldnt be exacly the same as my test program.
this is quite a difficult problem to describe withought showing the two programs side by side im open to any suggestions on how to exlain my problem better!
If anyone can think of anything why this might be happen i would be VERY grateful, ive been pulling my hair out over this for 2 weeks now!
Thank you for taking the time to read this ridiculasly long post
Here is the code in question for reference (i think posibly the bodge to create an OnClick function may be the source of the problem any suggestions on how to fix this would be brilliant!)
Here is the section in the header of the DLL that i think has the problem causer:
extern "C"
{
__declspec(dllexport)void SetTheHDC(HDC sentHDC);
__declspec(dllexport)void Render();
__declspec(dllexport)void CreateTheControls(TWinControl *SentPanel);
class aProgram : public TObject
{
__published:
void __fastcall TheButtonClick(TObject *Sender);
// I DONT LIKE the bodge here but it had to be published to work and that can only be done in a class, i tries using the (__closure) typedef but could not get it to work
private:
public:
};
aProgram *prog = new aProgram;
}
Here is the create controls function whithin the DLL:
void CreateTheControls(TWinControl* SentPanel)
{
Button1 = new TButton(SentPanel);
Button1->ParentFont = false;
Button1->Parent = SentPanel;
Button1->Left = 10;
Button1->Caption = "Pause";
Button1->Name = "TheButton";
Button1->Width = 100;
Button1->Height = 50;
Button1->Top = 50;
Button1->Visible = true;
Button1->Enabled = true;
Button1->OnClick = prog->TheButtonClick;
Button1->Click();
}
And the onclick function:
void __fastcall aProgram::TheButtonClick(TObject *Sender)
{
Pause = !Pause;
ShowMessage("Hello");
}
Here is the function that runs the DLL (sorry about the formatting):
void __fastcall TActiveTutorialForm::RunDLL()
{
//load in libary libary
dllhandle = LoadLibrary("MakeDllProjectFile.dll");//this->ActiveDllString.c_str());
if(!dllhandle)
{
ShowMessage("Unable to load DLL :-(, try again");
}
else
{
bool Abort = false;
//assign functions from DLL to functions created here
Render = (RENDER)GetProcAddress(dllhandle, "_Render");
SetHDC = (SETHDC)GetProcAddress(dllhandle, "_SetTheHDC");
CreateControls = (CREATECONTROLS)GetProcAddress(dllhandle, "_CreateTheControls");
Initialize = (INITIALISE)GetProcAddress(dllhandle, "_Initialize");
MouseMoveFunc = (MOUSEMOVE)GetProcAddress(dllhandle, "_MouseMove");
if(!Render)
{
Application->MessageBoxA("Render Function Doesnt Exist in dll file, aborting", "Fatal Error", MB_OK);
Abort = true;
}
if(!SetHDC)
{
Application->MessageBoxA("SetHDC Function Doesnt Exist in dll file, aborting", "Fatal Error", MB_OK);
Abort = true;
}
if(Abort)
{
return;// false;
}
else
{
//assign other possible functions
// this->OnKeyDown = (ONKEYDOWN)GetProcAddress(dllhandle, "_OnKeyDown"); //???
//finalise and activate
//ready application for openGL
hdc = GetDC(Handle);
SetPixelFormatDescriptor();
hrc = wglCreateContext(hdc);
if(hrc == NULL)
ShowMessage("hrc == NULL, sorry! try again");
if(wglMakeCurrent(hdc, hrc) == false)
ShowMessage("Could not MakeCurrent, sorry! try again");
width = this->OpenGlPanel->Width;
height = ClientHeight +(this->Height - (this->OpenGlPanel->Height));
this->FormStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
glClearColor(0.0f,0.0f,0.0f,0.0f);
glEnable(GL_DEPTH_TEST);
//begin the openGL-DLL application
SetHDC(hdc);
if(Initialize)
{
Initialize();
}
if(CreateControls)
{
CreateControls(this->ControlsInExamplePanel);
}
Application->OnIdle = IdleLoop;
FormResize(NULL);
Disabled = false;
}
}
//return true;
}
Everthing works apart from one (non-openGl) element the dll is meant to create a button on the form that can be used to pause the openGL. In my test program that i created it works perfectly however in my actuall program i have had an annoying problem with it. The dll creates the button on the form but when i click it, the button depresses but nothing happens, i know the function is assigned as a.) it works in my test program, b.) i force it to run at its creation using ->Click() which works. My tutor believes something has actually managed to damage the event message queue which would seem unlikely. He is an ex-industry programmer but he said this problem is so weird that i would actually need one of the programmers that designed Borland C++ builder. I am using v6 btw.
Everything is EXACTLY the same between the test prog and mine, they both loads up the DLL in the same way, run the same code everything is the same and from looking at it, it should WORK!
My problem took another wierd turn today, i changed my program again slightly. before my actual program loaded up the DLL while it was actually not visible whereas the test one was visible, so i changed my program to load the dll while visible and now the button doesnt show at all. I believe that maybe before the button somehow existed on the form virtually which is why it didnt run its event. I still dont understand why it shouldnt be exacly the same as my test program.
this is quite a difficult problem to describe withought showing the two programs side by side im open to any suggestions on how to exlain my problem better!
If anyone can think of anything why this might be happen i would be VERY grateful, ive been pulling my hair out over this for 2 weeks now!
Thank you for taking the time to read this ridiculasly long post
Here is the code in question for reference (i think posibly the bodge to create an OnClick function may be the source of the problem any suggestions on how to fix this would be brilliant!)
Here is the section in the header of the DLL that i think has the problem causer:
extern "C"
{
__declspec(dllexport)void SetTheHDC(HDC sentHDC);
__declspec(dllexport)void Render();
__declspec(dllexport)void CreateTheControls(TWinControl *SentPanel);
class aProgram : public TObject
{
__published:
void __fastcall TheButtonClick(TObject *Sender);
// I DONT LIKE the bodge here but it had to be published to work and that can only be done in a class, i tries using the (__closure) typedef but could not get it to work
private:
public:
};
aProgram *prog = new aProgram;
}
Here is the create controls function whithin the DLL:
void CreateTheControls(TWinControl* SentPanel)
{
Button1 = new TButton(SentPanel);
Button1->ParentFont = false;
Button1->Parent = SentPanel;
Button1->Left = 10;
Button1->Caption = "Pause";
Button1->Name = "TheButton";
Button1->Width = 100;
Button1->Height = 50;
Button1->Top = 50;
Button1->Visible = true;
Button1->Enabled = true;
Button1->OnClick = prog->TheButtonClick;
Button1->Click();
}
And the onclick function:
void __fastcall aProgram::TheButtonClick(TObject *Sender)
{
Pause = !Pause;
ShowMessage("Hello");
}
Here is the function that runs the DLL (sorry about the formatting):
void __fastcall TActiveTutorialForm::RunDLL()
{
//load in libary libary
dllhandle = LoadLibrary("MakeDllProjectFile.dll");//this->ActiveDllString.c_str());
if(!dllhandle)
{
ShowMessage("Unable to load DLL :-(, try again");
}
else
{
bool Abort = false;
//assign functions from DLL to functions created here
Render = (RENDER)GetProcAddress(dllhandle, "_Render");
SetHDC = (SETHDC)GetProcAddress(dllhandle, "_SetTheHDC");
CreateControls = (CREATECONTROLS)GetProcAddress(dllhandle, "_CreateTheControls");
Initialize = (INITIALISE)GetProcAddress(dllhandle, "_Initialize");
MouseMoveFunc = (MOUSEMOVE)GetProcAddress(dllhandle, "_MouseMove");
if(!Render)
{
Application->MessageBoxA("Render Function Doesnt Exist in dll file, aborting", "Fatal Error", MB_OK);
Abort = true;
}
if(!SetHDC)
{
Application->MessageBoxA("SetHDC Function Doesnt Exist in dll file, aborting", "Fatal Error", MB_OK);
Abort = true;
}
if(Abort)
{
return;// false;
}
else
{
//assign other possible functions
// this->OnKeyDown = (ONKEYDOWN)GetProcAddress(dllhandle, "_OnKeyDown"); //???
//finalise and activate
//ready application for openGL
hdc = GetDC(Handle);
SetPixelFormatDescriptor();
hrc = wglCreateContext(hdc);
if(hrc == NULL)
ShowMessage("hrc == NULL, sorry! try again");
if(wglMakeCurrent(hdc, hrc) == false)
ShowMessage("Could not MakeCurrent, sorry! try again");
width = this->OpenGlPanel->Width;
height = ClientHeight +(this->Height - (this->OpenGlPanel->Height));
this->FormStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
glClearColor(0.0f,0.0f,0.0f,0.0f);
glEnable(GL_DEPTH_TEST);
//begin the openGL-DLL application
SetHDC(hdc);
if(Initialize)
{
Initialize();
}
if(CreateControls)
{
CreateControls(this->ControlsInExamplePanel);
}
Application->OnIdle = IdleLoop;
FormResize(NULL);
Disabled = false;
}
}
//return true;
}