Page 1 of 1

Create PanelGadget about DLL

Posted: Wed Apr 26, 2006 9:34 pm
by funk.munich
Hi together,

with the following code I can create e.g. TextGadget from DLL to my
initialize window.

Code for EXE:

Code: Select all

OpenWindow(0,0,0,600,260,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"")
CreateGadgetList(WindowID(0))

container = ContainerGadget(#PB_Any,0,0,295,170)
CloseGadgetList()

OpenLibrary(1, "pb.dll")
CallFunction(1,"initPB", GadgetID(container))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

CloseWindow(0)
CloseLibrary(1)
Code for DLL:

Code: Select all

ProcedureDLL initPB(hWnd)

  UseGadgetList(hWnd)
  TextGadget(10,0,00,100,20,"hello world!")
  
EndProcedure
This works fine, but if I try to create TextGadget or whatever in a PanelGadget it doesn't work.

Has someone collect some experience with this such of problem
or know where I can find more information about this problem?

Background:
I'd like to use DLL as a Plugin. With this Plugin I want to set
additional Gadgets(Text, String, Panel) in the existing window.

Many thanks in advance for each suggestion.

Cheers
Daniel

Posted: Wed Apr 26, 2006 10:16 pm
by josku_x
I can't help you much as I don't know why it doesn't work, but I have to explain you something:

If you use code similar to this:

Code: Select all

TheButton=ButtonGadget(#PB_Any, ....)
It equals to the code like this:

Code: Select all

ButtonGadget(0, .....)
TheButton=GadgetID(0)
So, purebasic returns the system handle for the gadget if you use variable=ButtonGadget(#PB_Any, .....)

This means you should NOT use GadgetID(variable), but instead only pass the 'variable'. In cases you don't use #pb_any, it is better to use the GadgetID(#GadgetNumber)

Posted: Wed Apr 26, 2006 10:58 pm
by srod
So, purebasic returns the system handle for the gadget if you use variable=ButtonGadget(#PB_Any, .....)
Sorry Josh, but I don't think this is correct. The return from using #PB_Any is the gadget number and not the window's handle as you've suggested.

funk.munich: take care when creating a gadget in a dll as your normal code will not recognise the gadget number of 10 as identifying the text gadget. The dll has it's own 'space' for gadget numbers which is not shared with the main program. You'll have to return the text gadget's windows handle instead (GadgetID(10) etc.)

As for the panel gadget, each tab activates a container (a window's static control) and it is this whose gadget list you need to locate - not the underlying panel gadget. For this you will need a little Win API, depending on the particular circumstances.

Posted: Wed Apr 26, 2006 11:16 pm
by netmaestro
You're right srod, var = <command>(#PB_Any, ...) always results in var getting the #object, while var= <command>(#staticnumber, ...) results in var getting the handle. The behavior (oops, talking to srod! - 'behaviour') is the same for all objects.

Posted: Wed Apr 26, 2006 11:29 pm
by srod
:D

Posted: Thu Apr 27, 2006 12:37 am
by Konne
Hmmm I could help you but I don't like your name.

Posted: Thu Apr 27, 2006 7:25 am
by funk.munich
Hi together,

many thanks for the fast response.

Dear srod,

can you tell me which WIN API function(s) I need?

Dear Konne,

what's wrong with the name? It's only a name and I had thought that's
the forum exist to get help from other people - or not?

Thanks everyone,
Daniel

Posted: Thu Apr 27, 2006 7:35 am
by srod

Code: Select all

tci.TC_ITEM
tci\mask=#TCIF_PARAM	
SendMessage_(GadgetID(#panel), #TCM_GETITEM, GetGadgetState(#panel), tci)
Debug tci\lparam ;This holds the windows handle of the static control attached to the currently active tab.

Posted: Thu Apr 27, 2006 8:05 am
by funk.munich
Hi srod,

do you mean that I must enter this code in the DLL?
If yes ... I tried it but without any success.

Thanks,
Daniel

Posted: Thu Apr 27, 2006 8:18 am
by srod
No, because the dll will not recognise the gadget identified by #panel. Place the code in your main app and then call the dll with the value of tci\lparam as the parameter.

Posted: Thu Apr 27, 2006 8:34 am
by funk.munich
Hi,

if I am honest ... I don't understand it at the moment.
I should enter the WIN API call to exe:

Code: Select all

#panel = 5
OpenWindow(0,0,0,600,260,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"")
CreateGadgetList(WindowID(0))

PanelGadget(#panel,8,8,306,203)
AddGadgetItem (#panel,-1,"Panel 0")
;container = ContainerGadget(#PB_Any,0,0,295,170)
CloseGadgetList()

tci.TC_ITEM
tci\mask=#TCIF_PARAM   
SendMessage_(GadgetID(#panel), #TCM_GETITEM, GetGadgetState(#panel), tci) 

OpenLibrary(1, "pb.dll")
;CallFunction(1,"initPB", GadgetID(container))
CallFunction(1,"initPB", tci\lparam)  ; do you mean this?

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

CloseWindow(0)
CloseLibrary(1)
DLL:

Code: Select all

ProcedureDLL initPB(hWnd)

  UseGadgetList(hWnd)
  AddGadgetItem (hWnd,-1,"Panel 1")
  
EndProcedure
That doesn't work. ... because of that I haven't any experience with
WIN API I think that is completly wrong :-(

Do you have an example for me to understand it more deeply?

Sorry and thanks for your patience,
Daniel

Posted: Thu Apr 27, 2006 9:21 am
by srod
Sorry, I'm away from my PB computer until tonight, but your dll code looks a bit screwy to me.

As a test, try the following:

Code: Select all

ProcedureDLL initPB(hWnd) 

  UseGadgetList(hWnd) 
  ButtonGadget(10,0,0,60,20,"Test") 
  
EndProcedure 
See if this places a button on your panel.

Posted: Thu Apr 27, 2006 10:22 am
by funk.munich
Hi srod,

now it works. Great! :lol:
I modify a little bit more the code and now I can create new Panel
and include new Gadgets on this panel, too.

Many thanks,
Daniel

EXE:

Code: Select all

Procedure UpdateGadgetPointer(Library.l)
  Shared MainPointer.l
  !EXTRN _PB_Gadget_ObjectsArea
  !MOV dword EAX, [_PB_Gadget_ObjectsArea]
  !MOV dword [v_MainPointer], EAX
  CallFunction(Library, "SetGadgetPointer", MainPointer)
EndProcedure

Procedure getID(ID)

  tci.TC_ITEM
  tci\mask=#TCIF_PARAM   
  SendMessage_(GadgetID(ID), #TCM_GETITEM, GetGadgetState(ID), tci)
  
  ProcedureReturn tci\lparam
EndProcedure

Enumeration
  #Main
  #Panel
  #LIB
EndEnumeration

DLL.s = "pb.dll"

hWnd = OpenWindow(#Main,0,0,600,260,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"")

If CreateGadgetList(WindowID(*hWnd))

  PanelGadget(#Panel,8,8,306,203)
    AddGadgetItem (#Panel,-1,"Panel 1")
  CloseGadgetList()

  If OpenLibrary(#LIB, DLL)

    UpdateGadgetPointer(#LIB)
    
    ; Set one Button to Panel 1
    CallFunction(#LIB, "setBtn", getID(#Panel), 1)
    
    ; Create Panel 2
    CallFunction(#LIB, "setPanel", #Panel, 2)
    ; Create Button to 2nd Panel
    SetGadgetState(#Panel, 1)
    CallFunction(#LIB, "setBtn", getID(#Panel), 2)

  EndIf
EndIf

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

CloseWindow(#MAIN)
CloseLibrary(#LIB)
End
DLL:

Code: Select all

ProcedureDLL SetGadgetPointer(Pointer.l)
  Shared NewPointer.l
  NewPointer = Pointer
  !EXTRN _PB_Gadget_ObjectsArea
  !MOV dword EAX, [v_NewPointer]
  !MOV dword [_PB_Gadget_ObjectsArea], EAX
EndProcedure

ProcedureDLL setPanel(Gadget, no)

    AddGadgetItem (Gadget, -1, "Panel " + Str(no))
 
EndProcedure 

ProcedureDLL setBtn(hWnd, no)  
  
  UseGadgetList(hWnd)
  ButtonGadget(10 + no,20,20,60,20,"Test " + Str(no))     
 
EndProcedure 

Posted: Thu Apr 27, 2006 10:30 am
by srod
Nice little trick with the asm code. I like that! :D

Glad it's worked out.