DLL question

Just starting out? Need help? Post your questions and find answers here.
Yewklid
User
User
Posts: 19
Joined: Sun May 27, 2007 3:40 pm
Location: Berkshire, England

DLL question

Post by Yewklid »

I am learing how to write DLLs and have put togethet this very simple one.

Code: Select all

ProcedureDLL.s MyMessage()
  MessageRequester(Returnstring(), "This is a PureBasic DLL !", #PB_MessageRequester_YesNo )
  If Result = #PB_MessageRequester_Yes    
    a$ + "Yes"
  Else                                    
    a$ + "No"
  EndIf
ProcedureReturn a$
EndProcedure

ProcedureDLL MyWindow()
  If OpenWindow(0, 0, 0, 400, 300, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)    
  EndIf  
  Repeat 
    Event = WindowEvent() 
    If Event    
      
    Else  
      Delay(1)  
    EndIf 
  Until Event = #PB_Event_CloseWindow
EndProcedure
If I call MyMessage and MyWindow from a PB programme everything is fine. If I call from another language, it only works if I call MyMessage first and then MyWindow afterwards. If I try to call MyWindow first, nothing happens.
I can only guess that MyMessage must initialise something that MyWindow needs. Does anyone have any idea what is happening here and how I fix it?
Thanks
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: DLL question

Post by luis »

Yewklid wrote:I am learing how to write DLLs and have put togethet this very simple one.
Are you sure this one is that one ?

Where is Returnstring()?

a$ must be global.

From which language ?

How do you import it ?

How do you call it ?

etc. etc. etc.

Calling the messagerequester should cause the initialization of the common controls, but I don't know if has any relevance here. Maybe it has ? Not sure.

But I never created PB windows inside a DLL (and even less did so calling then the DLL from another language) so I don't have any experience with that.
"Have you tried turning it off and on again ?"
A little PureBasic review
Yewklid
User
User
Posts: 19
Joined: Sun May 27, 2007 3:40 pm
Location: Berkshire, England

Re: DLL question

Post by Yewklid »

Hi Luiz,

I should have taken out Returnstring because it is not relevant. It can be replaced by a fixed string like this:

Code: Select all

ProcedureDLL.s MyMessage()
  MessageRequester("Hello", "This is a PureBasic DLL !", #PB_MessageRequester_YesNo )
  If Result = #PB_MessageRequester_Yes   
    a$ + "Yes"
  Else                                   
    a$ + "No"
  EndIf
ProcedureReturn a$
EndProcedure
You are also right that MyMessage does not return the correct value because of the lack of Global variable (but I don't mind at the moment).
The main point though is that the MessageRequester window does pop up and my question is why the window in MyWindow only pops up if the other one has appeared first. Your answer about the Common Controls is the kind of issue I thought might be involved but I would love to know how to use this to solve the problem.

The other language is called Lhogho and the other simple examples I have tried in a DLL like doubling numbers and things like that have all worked fine.

I am using the proper method for loading and calling functions in a DLL in Lhogho and here is an example:

Code: Select all

make "Turtlelib libload "TurtleDLL.dll
if :Turtlelib=0     
  [print [TurtleLib not loaded]]
  [print [TurtleLib loaded]]

to MyMessage end
external "MyMessage [s1 MyMessage] :Turtlelib

make "ans MyMessage
print :ans

The context here is that I am interested in writing a DLL to implement Turtle graphics which is something which is popular in languages for teaching youngsters to programme.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: DLL question

Post by luis »

OK thanks (I admit the language info didn't help me since I don't know nothing about it :mrgreen: )
About the common controls, as I said I don't know if it's relevant since you are trying to create an empty window but you can try to call InitCommonControlsEx with at least the ICC_STANDARD_CLASSES bit set and see if it changes anything.

http://msdn.microsoft.com/en-us/library ... 85%29.aspx

You could also try to create an empty window through API to see if that one works without any previous call or not.

You can steal from this snippet to waste less time -> http://www.purebasic.fr/english/viewtop ... 76#p397876

You could also log some debug message to file to see where exactly is the point which fails.

Or use OutputDebugString()
http://technet.microsoft.com/en-us/sysi ... 96647.aspx

I don't have idea of what I'm saying here.
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: DLL question

Post by Danilo »

Works with PB itself.

EXE:

Code: Select all

If OpenLibrary(0,"theDll.dll")
    ;CallFunction(0,"MyMessage")
    CallFunction(0,"MyWindow")
    CloseLibrary(0)
EndIf
DLL:

Code: Select all

ProcedureDLL.s MyMessage()
  MessageRequester("Hello", "This is a PureBasic DLL !", #PB_MessageRequester_YesNo )
  If Result = #PB_MessageRequester_Yes    
    a$ + "Yes"
  Else                                    
    a$ + "No"
  EndIf
ProcedureReturn a$
EndProcedure

ProcedureDLL MyWindow()
  If OpenWindow(0, 0, 0, 400, 300, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)    
  EndIf  
  Repeat 
    Event = WindowEvent() 
    If Event    
      
    Else  
      Delay(1)  
    EndIf 
  Until Event = #PB_Event_CloseWindow
  CloseWindow(0)
EndProcedure
(Had to add CloseWindow(), otherwise the EXE process does not exit and stays in task manager)
Yewklid
User
User
Posts: 19
Joined: Sun May 27, 2007 3:40 pm
Location: Berkshire, England

Re: DLL question

Post by Yewklid »

Your suggestion about the common controls is the best clue I have so far. I'll have a look at your links and try some experiments.

Many thanks
Yewklid
User
User
Posts: 19
Joined: Sun May 27, 2007 3:40 pm
Location: Berkshire, England

Re: DLL question

Post by Yewklid »

Fantastic. Creating a window through the API works. Thanks.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: DLL question

Post by luis »

But does it help you ? I thought you needed a PB window. If not, then fine :wink:
"Have you tried turning it off and on again ?"
A little PureBasic review
Yewklid
User
User
Posts: 19
Joined: Sun May 27, 2007 3:40 pm
Location: Berkshire, England

Re: DLL question

Post by Yewklid »

All I really need to do is be able to draw line segments to the window which has just been created. I'm guessing that can be done through the API as well although I will need to read up how to do that. That could be one way forward.

I haven't yet figured out your other suggestion. I know that it translates into a PB call of the form InitCommonControlsEx_() but I haven't figured out the " the ICC_STANDARD_CLASSES bit set'" part of it yet.
Yewklid
User
User
Posts: 19
Joined: Sun May 27, 2007 3:40 pm
Location: Berkshire, England

Re: DLL question

Post by Yewklid »

hmmm......I've just found one sneaky way round the problem. If I use your API code to create a window but don't actually show it then I can open a window using PB code in the normal way and use all the usual line drawing code provided by PB.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: DLL question

Post by luis »

Yewklid wrote: I haven't yet figured out your other suggestion. I know that it translates into a PB call of the form InitCommonControlsEx_() but I haven't figured out the " the ICC_STANDARD_CLASSES bit set'" part of it yet.
I believe you can do this way:

Code: Select all

Procedure.i InitCC()
 Protected initcc.INITCOMMONCONTROLSEX
 initcc\dwSize = SizeOf(INITCOMMONCONTROLSEX)
 initcc\dwICC = #ICC_STANDARD_CLASSES ; (add others if needed using '|')
 ProcedureReturn InitCommonControlsEx_(@initcc)
EndProcedure

Debug InitCC()
Try to call InitCC() before opening the PB window, if doesn't work try to add the most common flags, if still doesn't work probably this has nothing to do with your problem :)

If Fred read this I'm sure he could tell you what the prerequisites are to open a PB window not from a normal exe (maybe something called by PB during its initialization ?).

If it works you can try to move it inside the special AttachProcess() procedure. See DLL in the help for more info.
"Have you tried turning it off and on again ?"
A little PureBasic review
Yewklid
User
User
Posts: 19
Joined: Sun May 27, 2007 3:40 pm
Location: Berkshire, England

Re: DLL question

Post by Yewklid »

Haven't managed to find a flag that works yet.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: DLL question

Post by luis »

Yewklid wrote:If I use your API code to create a window but don't actually show it then I can open a window using PB code in the normal way and use all the usual line drawing code provided by PB.
That's weird, no idea why. But if it works... maybe you can create the window and destroy it right away ?
"Have you tried turning it off and on again ?"
A little PureBasic review
Yewklid
User
User
Posts: 19
Joined: Sun May 27, 2007 3:40 pm
Location: Berkshire, England

Re: DLL question

Post by Yewklid »

Excellent idea. I tried it and it works :D

Thanks for all your help in getting this sorted!
Post Reply