Page 1 sur 2

Import/Endimport et tout le toutim [Resolu]

Publié : lun. 03/nov./2008 18:23
par Kwai chang caine
Bonjour a tous

Kcc se lance dans une nouvelle aventure les "Import/Endimport"
Grace a une reponse de Meganet que j'ai trouvé super interessante.
Une fois FLYPE m'avais déjà expliqué, mais j'avais pas percuté.

http://www.purebasic.fr/french/viewtopi ... 8897#88897

Mais cette fois, j'ai cru comprendre a quoi servait cette fonction.
Erreur grave :?

J'ai seulement que cru :oops:

J'ai fait une DLL, donc en la compilant j'ai obtenu un fichier .lib.
Dans cette DLL je liste les process en cours et je les ecris dans une ListViewGadget dont le PbId "#ListviewProcess" a été transmis par parametres

J'ai fait un

Code : Tout sélectionner

#FormList = 0
#ListviewProcess = 10

OpenWindow(#FormList, 372, 174, 457, 255, "ListAllProcess", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
CreateGadgetList(WindowID(#FormList))
ListViewGadget(#ListviewProcess, 14, 10, 431, 193)

Import "MaDll.lib"
 ListeProcessCourt(IdGadgetList)
EndImport

ListeProcessCourt(#ListviewProcess)

Repeat  
 
 Evenement = WaitWindowEvent () 
 
Until Evenement = #PB_Event_CloseWindow
Et evidemment ça marche pas. :cry:
Mais c'est peut etre normal, car moi je voulais faire ecrire ma DLL dans un listgadget qui est dans mon programme.
Je pense qu'il n'est pas possible de lui passer le PbId a la DLL.
Peut etre faut il travailler avec le handle du GadgetList ???

Bref, j'ai encore compris quedal :cry:

Si une ame charitable pouvait ramasser une PureSerpillere de programmeur, ce serais sympa :D

Bonne soirée

Publié : lun. 03/nov./2008 18:36
par Anonyme2
KCC, il manque le code de la dll pour tester :D

Publié : lun. 03/nov./2008 21:30
par Kwai chang caine
T'as raison, qu'il est bete ce KCC ouarff !!ouarff !! ouarff !!
Merci de ton aide mon bon denis 8)

Code : Tout sélectionner

ProcedureDLL ListeProcessCourt(IdGadgetList) 
 
 #TH32CS_SNAPHEAPLIST = $1 
 #TH32CS_SNAPPROCESS = $2 
 #TH32CS_SNAPTHREAD = $4 
 #TH32CS_SNAPMODULE = $8 
 #TH32CS_SNAPALL = #TH32CS_SNAPHEAPLIST | #TH32CS_SNAPPROCESS | #TH32CS_SNAPTHREAD | #TH32CS_SNAPMODULE 
 #TH32CS_INHERIT = $80000000 
 #INVALID_HANDLE_VALUE = -1 
 #MAX_PATH = 260 
 #PROCESS32LIB = 9999 
 #PSAPI = 9998 

 If OpenLibrary (#PROCESS32LIB, "kernel32.dll") 

  Snap = CallFunction (#PROCESS32LIB, "CreateToolhelp32Snapshot", #TH32CS_SNAPPROCESS, 0) 
 
  If Snap 
   
   Define.PROCESSENTRY32 Proc32 
   Proc32\dwSize = SizeOf (PROCESSENTRY32) 
   
   If CallFunction (#PROCESS32LIB, "Process32First", Snap, @Proc32) 
          
    While CallFunction (#PROCESS32LIB, "Process32Next", Snap, @Proc32) 
      
     Process.s = PeekS(@Proc32\szExeFile)
    
     If Trim(Process) <> ""
      
      If IsGadget(IdGadgetList)
       AddGadgetItem(IdGadgetList, - 1, Process)
      Else
       Debug Process
      EndIf
       
     EndIf  
       
    Wend      
    
    EndIf    
  
   CloseHandle_(Snap) 
  
  EndIf 
  
  CloseLibrary (#PROCESS32LIB) 
 
 EndIf 

EndProcedure

Publié : mar. 04/nov./2008 7:46
par Anonyme2
KCC,

après essai, le gadget n'est pas reconnu dans la dll, c'est le seul problème.

J'ai essayé avec attachprocess mais rien, d'ailleurs la doc est à revoir à fond, je ne sais pas ce que c'est que Instance, s'il faut appeler ou non Attachprocess ou si c'est PB qui le fait.

Sur tes message du forum anglais, Tinman pensait que :
I thought that a DLL and an executable written in PB could not easily share their objects. I mean, the DLL will have it's own library objects and the EXE will have it's own library objects.
Je pense aussi que les objets (gadgets et autres) sont propres au programme et pas à la Dll. Sauf si Fred montre comment faire.

Je te propose une autre approche qui fonctionne, c'est dans le même ordre d'idée des callback de MS

Je crée une procedure qui va remplir la listview. Cette procedure va être appelée par la dll autant de fois qu'il y a de process.

On passe à la dll le gadget et l'adresse de la procedure.
J'ai déclaré en global la variable Process.s dans la dll

Tu peux ajouter un test sur la valeur de *Callback qui doit être différent de 0

Code : Tout sélectionner

ProcedureDLL ListeProcessCourt(IdGadgetList, *Callback)
     
     #TH32CS_SNAPHEAPLIST = $1
     #TH32CS_SNAPPROCESS = $2
     #TH32CS_SNAPTHREAD = $4
     #TH32CS_SNAPMODULE = $8
     #TH32CS_SNAPALL = #TH32CS_SNAPHEAPLIST | #TH32CS_SNAPPROCESS | #TH32CS_SNAPTHREAD | #TH32CS_SNAPMODULE
     #TH32CS_INHERIT = $80000000
     #INVALID_HANDLE_VALUE = -1
     #MAX_PATH = 260
     #PROCESS32LIB = 9999
     #PSAPI = 9998
     
     Global Process.s = ""
     
     If OpenLibrary(#PROCESS32LIB, "kernel32.dll")
          Snap = CallFunction(#PROCESS32LIB, "CreateToolhelp32Snapshot", #TH32CS_SNAPPROCESS, 0)
          
          If Snap
               
               Define.PROCESSENTRY32 Proc32
               Proc32\dwSize = SizeOf(PROCESSENTRY32)
               
               If CallFunction(#PROCESS32LIB, "Process32First", Snap, @Proc32)
                    
                    While CallFunction(#PROCESS32LIB, "Process32Next", Snap, @Proc32)
                         Process.s = PeekS(@Proc32\szExeFile)
                         
                         If Trim(Process)<>""
                              CallFunctionFast(*Callback, Process, IdGadgetList)
                         EndIf 
                         
                    Wend 
                    
               EndIf 
               
               CloseHandle_(Snap)
               
          EndIf
          
          CloseLibrary(#PROCESS32LIB)
          
     EndIf
     
EndProcedure

et l'utilisation

Code : Tout sélectionner

#FormList = 0
#ListviewProcess = 10


Procedure EnumereProcesses(Process$, IDGagdet)
     
     If IsGadget(IDGagdet)
          AddGadgetItem(IDGagdet, -1, Process$)
     EndIf
     
EndProcedure


OpenWindow(#FormList, 372, 174, 457, 255, "ListAllProcess", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(#FormList))
ListViewGadget(#ListviewProcess, 14, 10, 431, 193)



Import "MaDll.lib"
     ListeProcessCourt(IdGadgetList, *Callback)
EndImport

; If OpenLibrary(0, "MaDll.dll")
;      CallFunction(0, "ListeProcessCourt", #ListviewProcess, @EnumereProcesses())
; EndIf

ListeProcessCourt(#ListviewProcess, @EnumereProcesses()) 


Repeat 
     
     Evenement = WaitWindowEvent()
     
Until Evenement = #PB_Event_CloseWindow

Publié : mar. 04/nov./2008 8:57
par Kwai chang caine
Merci bien DENIS tu es un ange 8)
Si toi tu y arrivais pas, j'ai bien fait de pas trop insister.

En plus je viens de regarder ton code c'est de la haute voltige, j'etais pas pret de pondre un oeuf comme ça, meme si je force beaucoup :oops:

Je me doutais que y'avais une histoire de non reconnaissance.
Comment je fais pour toujours avoir besoin de ce qui est pas possible :?

Mais heureusement que y'a mes super heros 8)
Qui viennent avec leur cape (parce que moi, j'ai pas le droit a la cape :cry:, je suis encore trop petit, j'ai essayé avec un mouchoir, mais je me vautre irremediablement par terre :lol:)

Encore merci, je vais essayer ça

Excelente journée a toi

Publié : mar. 04/nov./2008 9:31
par PAPIPP
Je suis entièrement d'accord avec Denis

Code : Tout sélectionner

après essai, le gadget n'est pas reconnu dans la dll, c'est le seul problème.

J'ai essayé avec attachprocess mais rien, d'ailleurs la doc est à revoir à fond, je ne sais pas ce que c'est que Instance, s'il faut appeler ou non Attachprocess ou si c'est PB qui le fait.

Sur tes message du forum anglais, Tinman pensait que :
Citation:
I thought that a DLL and an executable written in PB could not easily share their objects. I mean, the DLL will have it's own library objects and the EXE will have it's own library objects.


Je pense aussi que les objets (gadgets et autres) sont propres au programme et pas à la Dll. Sauf si Fred montre comment faire. 
Voici ce que je propose
J'intègre la partie Edition dans la DLL
ce qui me donne la DLL (malist) suivante

Code : Tout sélectionner

; Declare ListeProcessCourt()
; listeprocesscourt()
; End
; ; Code:
ProcedureDLL ListeProcessCourt()
  ;Declare ListeProcessCourt(IdGadgetList)
  #FormList = 0
  #ListviewProcess = 100
  
  OpenWindow(#FormList, 372, 174, 457, 255, "ListAllProcess", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
  CreateGadgetList(WindowID(#FormList))
  resultat = ListViewGadget(#ListviewProcess, 14, 10, 431, 193)
  idgadgetlist = #listviewprocess
  
  ;
  debut_list:
  #TH32CS_SNAPHEAPLIST = $1
  #TH32CS_SNAPPROCESS = $2
  #TH32CS_SNAPTHREAD = $4
  #TH32CS_SNAPMODULE = $8
  #TH32CS_SNAPALL = #TH32CS_SNAPHEAPLIST | #TH32CS_SNAPPROCESS | #TH32CS_SNAPTHREAD | #TH32CS_SNAPMODULE
  #TH32CS_INHERIT = $80000000
  #INVALID_HANDLE_VALUE = -1
  #MAX_PATH = 260
  #PROCESS32LIB = 9999
  #PSAPI = 9998
  
  If OpenLibrary(#PROCESS32LIB, "kernel32.dll")
    
    Snap = CallFunction(#PROCESS32LIB, "CreateToolhelp32Snapshot", #TH32CS_SNAPPROCESS, 0)
    
    If Snap
      
      Define.PROCESSENTRY32 Proc32
      Proc32\dwSize = SizeOf(PROCESSENTRY32)
      
      If CallFunction(#PROCESS32LIB, "Process32First", Snap, @Proc32)
        
        While CallFunction(#PROCESS32LIB, "Process32Next", Snap, @Proc32)
          
          Process.s = PeekS(@Proc32\szExeFile)
          
          If Trim(Process)<>""
            
            If IsGadget(IdGadgetList)
              AddGadgetItem(IdGadgetList, -1, Process)
            Else
              Debug Process
            EndIf
            
          EndIf
          
        Wend
        
      EndIf
      
      CloseHandle_(Snap)
      
    EndIf
    
    CloseLibrary(#PROCESS32LIB)
    
  EndIf
  Repeat
    
    Evenement = WaitWindowEvent()
    
  Until Evenement = #PB_Event_CloseWindow
  
  :
  
EndProcedure
A compiler sous le nom de malist.dll ou malist.lib
et à placer dans un répertoire qui permette à Plink de la connaitre
Voici les deux tests que j'ai pu réaliser avec cette DLL en prototype
et en import

Code : Tout sélectionner

;;;*****PROTOTYPE****
Prototype.l Protolistprocess()

If OpenLibrary(0, ".\malist.dll")
  
  ; 'MsgBox' est une variable de type 'ProtoMessageBox'
  ;
  listproc.Protolistprocess = GetFunction(0, "ListeProcessCourt")
  
  listproc() ; Les options peuvent être omises
EndIf

MessageRequester("Type d'appel", "Appel par prototype", #PB_MessageRequester_Ok)
Import "malist.lib"
  ;ListeProcessCourt() As "_ListeProcessCourt@0"
  ListeProcessCourt()
EndImport
ListeProcessCourt()
MessageRequester("Type d'appel", "Appel par Import", #PB_MessageRequester_Ok)
:P

Publié : mar. 04/nov./2008 9:45
par Kwai chang caine
ça marche !!!!!!

J'en reviens pas comme les paquets de "BONUSQUE" deux pour le prix d'un.
Merci les amis 8)

Mais comment vous faites, parfois quand j'ai la reponse a un de mes problemes, j'suis super heureux, mais en meme temps cela me fait contempler le haut de la montagne, et me rendre compte avec effroi que la route va etre encore longue et sinueuse :cry:

Encore mille merci
A nouveau internet vous protege d'une bonne bise baveuse ou d'une etreinte dans mes petits bras "musqués" :D

Bonne journée a vous et tous le forum

Publié : mar. 04/nov./2008 10:07
par Kwai chang caine
Bon je viens de tester les deux methodes, mais je vais utiliser celle de DENIS, qui est plus proche de ce que j'avais au depart.
Le probleme avec la methode de PAPIPP, c'est qu'il faut tout mettre les gadgets dans la DLL, donc le programme ne sert plus a grand chose en fin de compte
J'ai voulu rajouter un bouton pour tuer les process désirés, ça a marché nickel avec la methode DENIS.
Pour la methode PAPIPP j'ai rajouté le bouton dans la DLL et apres je n'ai pas pu gerer l'evenement dans le programme.

De plus, un grand du forum US m'a dit, qu'il fallait eviter les boucles d'attente dans les DLL, que c'etait risqué, je pense que c'est parce que si on perd la liaison DLL elle reste a tourner toute seule en attendant qu'on la retrouve :D

Quoi qu'il en soit encore merci a vous deux
Grace a vous KCC y continue son avneture au pays de la programmation.

A la prochaine buche :wink:

Publié : mar. 04/nov./2008 11:25
par Le Soldat Inconnu
A la prochaine buche
vivement la buche de noël :roll:

Publié : mar. 04/nov./2008 11:37
par Kwai chang caine
Ouaih encore des kilo en plus, et c'est pas des kilooctets, je peux te l'assurer :?

J'ai encore une question, sur les imports.

Si je fais un import comme ça

Code : Tout sélectionner

Import "MaDll.lib" 
 ListeProcessCourt(IdGadgetList) 
EndImport 
Est ce que y'a un moyen apres de modifier le chemin de la DLL.
Ou bien de lui dire de chercher la DLL a deux endroits differents :roll:
Du style

Code : Tout sélectionner

..\System\MaDll.dll

Publié : mar. 04/nov./2008 13:02
par Anonyme2
Tu as essayé Import "..\System\MaDll.dll.lib" avec les deux chemin différents et biens sur 2 dll différentes avec un code différent pour voir si vraiment c'est bon ?

Path

Publié : mar. 04/nov./2008 13:06
par meganet
Salut, si je nm’abuses, ton programme ira chercher ta dll soit dans son rep de base, soit dans les répertoires inscrits dans la variable path. Voilà! Donc si tu veux utiliser ta dll pour plusieurs programmes, mais la dans C:\Windows\system32\ et elle sera accessible pour tous!!
Voilà @+++.

Publié : mar. 04/nov./2008 13:39
par Kwai chang caine
Tu as essayé Import "..\System\MaDll.dll.lib" avec les deux chemin différents et biens sur 2 dll différentes avec un code différent pour voir si vraiment c'est bon ?
Pour mes applications, j'ai prevu deux modes d'installation.
Une en pack
Une en solo

Pour celle en solo tout baigne comme vous m'avez montré.
La DLL est dans le repertoire de l'exe.

Mais pour le pack, etant donné que chaque appli a son propre repertoire, j'ai decidé de creer un repertoire "Systeme" dans lequel je met toutes mes DLL qui seront donc communes a toutes mes applis :D .

Voila l'arborescence du pack :

Code : Tout sélectionner

                                          Rep KCCPack
                                                   |
                                                   |
                                                   V
          Rep Applications            Rep Systeme                Rep Donnes      
                     |                          |                        | 
                     |                          |                        | 
                     V                          V                        V
            Rep Appli1                        Dll1.dll
            Rep Appli2                        Dll1.dll
Donc quand je fait un loadlibrary, je verifie d'abord si la DLL que j'appelle est dans le dossier systeme de mon pack, et si c'est le cas il s'arrette la et l'utilise.
Si c'est pas le cas, il va voir dans le repertoire de l'appli, et si il la trouve il utilise celle la
Comme ça, en priorité, il utilise la DLL du pack si il est pas en solo

Seulement voila comment faire avec les import/endimport puisque si je lui donne le chemin de mon repertoire KCCPack\Systeme et que le prog est en solo ça va planter, et si je lui donne aucun chemin et qu'il est en pack ça va planter aussi :cry:
Salut, si je nm’abuses, ton programme ira chercher ta dll soit dans son rep de base, soit dans les répertoires inscrits dans la variable path. Voilà! Donc si tu veux utiliser ta dll pour plusieurs programmes, mais la dans C:\Windows\system32\ et elle sera accessible pour tous!!
Merci MEGANET, mais quoi qu'il en soit j'ai juste deux endroits ou elle peut etre soit dans le dossier de l'appli, soit dans mon repertoire systeme.
Je ne veux pas utiliser le cas du system32, car les machines sur lequel je bosse sont blindé a mort et on ne peux rien copier sans autorisations.
C'est d'ailleurs pour ça que j'ai abandonné les DLL ActiveX de VB et que j'utilise que les standard, comme ça pas de BDR, et pas de chemin system obligatoire :D

Path usr

Publié : mer. 05/nov./2008 0:29
par meganet
Salut, tu peux ajouter ton rep au path de l'utilisateur. Tu peux faire ça sur (2k, xp, 2k3, vista, 2k8). Comme ça pas de problème d'accès et d'autorisation (normalement ta tous les droits sur ton rep utilisateur).

Publié : mer. 05/nov./2008 6:04
par Kwai chang caine
Excuse moi, mais j'ai pas compris par "rejouter ton rep au path de l'utilsateur"