Nouveautés: - EvaluateExpression: le message d'erreur en cas de fonction invalide est supprimé.
Modules modifiés: KGF.dll
La doc est inchangée.
C'est une simple mise à jour technique sans changements de fonctionnalités.
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: KGF_dll - nouvelles versions Dim 10 Jan 2021 - 10:13
KGF.dll V9.43 du 10/01/2021
Nouveautés: - nouvel objet: KGFFileStream et ses fonctions de support - nouvel objet: MemoryTree et ses fonctions de support - nouvelles fonctions: ExpandTreeView, LoadTreeViewFromText
Modules modifiés: KGF.dll KGF.chm
La doc est à jour.
Ceci est une mise à jour majeure !
Les deux nouvelles fonctions concernant TreeView sont des extensions de fonctionnalités pour un objet existant.
Par contre, les deux nouveaux objets représentent un ajout important dont vous ne découvrirez l'utilité que progressivement.
D'abord, MemoryTree: C'est un objet similaire à TreeView, mais c'est un objet non-visuel. Il est géré uniquement en mémoire. Pour afficher son contenu, on peut utiliser on MEMO ou un LIST Panoramic, ou un TreeView de KGF.dll. Cet objet sert à gérer des structures logiques arborescentes, sans avoir à se soucier de la présentation visuelle. Les domaines d'application sont vastes: généalogie, pièces détachées, gestion de projets (notamment en développement !), organigrammes d'entreprise avec les personnes attachées à chaque service, etc.
Voici une démo. Cliquez sur "Créer", puis "Peupler". Rien ne semble se passer puisque c'est un objet non visuel. Pourtant, une structure logique arborescente est bien créée. Cliquez alors sur "Afficher" et vous verrez le résultat. On peut ensuite naviguer la la structure avec les boutons présents, la modifier ou cliquer sur un des éléments affichés. La structure est ajustée et l'affichage est chaue fois automatiquement corrigé.
Code:
' test_MemoryTree.bas
' Ce programme de démo montre les fonctionnalités de l'objet MemoryTree. ' Toutes les fonctions agissent uniquement sur l'objet non visuel en mémoire. ' Pour visualiser le résultat, un objet Panoramic MEMO est utilisé pour afficher ' le texte courant tu MemoryTree, et un objet TreeView de KGF.dll est utilisé ' pour représenter ce contenu visuellement sous la forme d'un arbre. ' Les noeuds dans l'objet TreeView peuvent être sélectionnés par un clic gauche. ' Le noeud ainsi sélectionné devient le noeud sur lequel certaines actions ' s'appliquent, comme "Soeur suivant", "Parent", "Insérer" etc.
close0: if TV%<>0 then res% = dll_call3("SetTreeViewEventReceiver",TV%,0,0) if MT%<>0 then MT% = dll_call1("DeleteMemoryTree",MT%) if TV%<>0 then TV% = dll_call2("DeleteTreeView",TV%,1) return
Ensuite, KGFFileStream. Cet objet est un nouveau moyen d'écrire des données dans un fichier et de les relire. Un tel objet gère un fichier "container" dans lequel on peut placer des variables simples Panoramic, des tableaux (unidimensionnels) Panoramic ainsi que des fichiers. L'objet gère un répertoire des données qu'il contient et on peut à tout moment récupérer une donnée spécifique. C'est idéal pour sauvegarder des données hétéroclites d'une application dans un seul fichier. Facilité de distriutioin d'un logiciel, simplification des saivegardes, sauvegarde de l'état d'un programme puisqu'on peut y placer des variables Panoramic, etc. Les applications sont vastes. Voici une démo. L'utilisation est simple et découle directement des libellés de boutons.
getsegment: index% = val(text$(32)) segtype% = dll_call2("GetKGFFileStreamSegmentType",FS%,index%) if segtype%<0 if segtype%=-1 message "Ce fichier ne contient aucun segment" else message "Index hors limites - doit être entre 1 et "+str$(0-segType%-1) end_if return end_if
select segtype% case 0: ' TEXT ' il faut donner un espace suffisant pour recevoir le string ! txt$ = string$(500," ") res% = dll_call3("ExtractKGFFileStreamSegment",FS%,index%,adr(txt$)) message str$(res%)+" "+trim$(txt$) return case 1: ' INTEGER ' effacement des données est inutile - juste pourprouver que la restauration a bien eu lieu n% = 0 res% = dll_call3("ExtracKGFtFileStreamSegment",FS%,index%,adr(n%)) message str$(res%)+" "+str$(n%) return case 2: ' FLOAT ' effacement des données est inutile - juste pourprouver que la restauration a bien eu lieu v = 0 res% = dll_call3("ExtractKGFFileStreamSegment",FS%,index%,adr(v)) message str$(res%)+" "+str$(v) return case 3: ' FILE nom$ = 'FichierEnSortie.dat" res% = dll_call3("ExtractKGFFileStreamSegment",FS%,index%,adr(nom$)) if res%=0 then message str$(res%)+" enregistré dans "+nom$ if res%<0 then message str$(res%) return case 4: ' TEXTARRAY textarray$(0) = " " textarray$(1) = " " textarray$(2) = " " textarray$(3) = " " textarray$(4) = " " res% = dll_call3("ExtractKGFFileStreamSegment",FS%,index%,adr(textArray$)) : ' retour en textArray$ res% = dll_call3("ExtractKGFFileStreamSegment",FS%,index%,handle(100)) : ' retour en mémo message str$(res%)+" "+textarray$(0)+chr$(13)+chr$(10)+textarray$(1)+chr$(13)+chr$(10)+textarray$(2)+chr$(13)+chr$(10)+textarray$(3)+chr$(13)+chr$(10)+textarray$(4) return case 5: ' INTEGERARRAY ' effacement des données est inutile - juste pourprouver que la restauration a bien eu lieu integerarray%(0) = 0 integerarray%(1) = 0 integerarray%(2) = 0 integerarray%(3) = 0 res% = dll_call3("ExtractKGFFileStreamSegment",FS%,index%,adr(integerarray%)) message str$(res%)+" "+str$(integerarray%(0))+" "+str$(integerarray%(1))+" "+str$(integerarray%(2))+" "+str$(integerarray%(3)) return case 6: ' FLOATARRAY ' effacement des données est inutile - juste pourprouver que la restauration a bien eu lieu floatarray(0) = 0 floatarray(1) = 0 floatarray(2) = 0 floatarray(3) = 0 floatarray(4) = 0 floatarray(5) = 0 res% = dll_call3("ExtractKGFFileStreamSegment",FS%,index%,adr(floatarray)) message str$(res%)+" "+str$(floatarray(0))+" "+str$(floatarray(1))+" "+str$(floatarray(2))+" "+str$(floatarray(3))+" "+str$(floatarray(4))+" "+str$(floatarray(5)) return end_select message "Oups... type de segment non prévu: "+str$(segtype%) return
Initialement, j'avais prévu de publier cela luste avant Noël, en guise de cadeau. Mais la fabrication de la doc m'a pris beaucoup plus de temps que prévu. Donc, ce sera ma contribution pour ouvrir cette Nouvelle Année en beauté, en y ajoutant une pointe de créativité et d'optimisme.
Une excellente Nouvelle Année 2021 à tous les Panoramiciens !
Dernière édition par Klaus le Mar 12 Jan 2021 - 13:19, édité 1 fois
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Ceci est un petit ajout à l'objet MemoryTree. Maintenant, chaque noeud peut avoir des données optionnelles sous forme d'une chaîne de caractères non limitée. Ces données sont optionnelles et ne changent la structure en rien. Elles sont distinctes du nom du noeud (de son libellé). Ces fonctions permettent de changer les données texte pour un noeud et de les relire.
Le programme de démo a été étendu à ces nouvelles fonctions:
Code:
' test_MemoryTree.bas
' Ce programme de démo montre les fonctionnalités de l'objet MemoryTree. ' Toutes les fonctions agissent uniquement sur l'objet non visuel en mémoire. ' Pour visualiser le résultat, un objet Panoramic MEMO est utilisé pour afficher ' le texte courant tu MemoryTree, et un objet TreeView de KGF.dll est utilisé ' pour représenter ce contenu visuellement sous la forme d'un arbre. ' Les noeuds dans l'objet TreeView peuvent être sélectionnés par un clic gauche. ' Le noeud ainsi sélectionné devient le noeud sur lequel certaines actions ' s'appliquent, comme "Soeur suivant", "Parent", "Insérer" etc. ' Ob peut affecter une chaîne de caractères aux données "string" d'un noeud. ' Le clic sur un noeud à gauche affiche également les données string du noeud (s'il y en a).
close0: if TV%<>0 then res% = dll_call3("SetTreeViewEventReceiver",TV%,0,0) if MT%<>0 then MT% = dll_call1("DeleteMemoryTree",MT%) if TV%<>0 then TV% = dll_call2("DeleteTreeView",TV%,1) return
chgMS: if nodeMT%=0 then return txt$ = text$(92) res% = dll_call3("ChangeMemoryTreeNodeStringData",MT%,nodeMT%,adr(txt$)) return
Marc
Nombre de messages : 2466 Age : 63 Localisation : TOURS (37) Date d'inscription : 17/03/2014
Sujet: Re: KGF_dll - nouvelles versions Jeu 14 Jan 2021 - 1:17
Merci Klaus !
C‘est impressionnant !
J’ai relevé deux petites coquilles dans la documentation :
- Fonction AddTreeViewRootNode : un dll_call3(…) au lieu de dll_call4(…)
Spoiler:
- La documentation de LoadTreeViewFromText affiche celle de LoadTreeViewFromFile lorsque l'on passe par "Index > Objet Tree View > LoadTreeViewFromText".
Spoiler:
Autre sujet : Sous windows 10, la fonction ShowFormScrollBars semble inactive. Elle renvoie bien 0 en retour, mais les scrollbars ne s’affichent pas.
Bonne continuation !
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: KGF_dll - nouvelles versions Jeu 14 Jan 2021 - 2:52
Merci pour tes remarques, Marc !
Les "coquilles" seront corrigées dans la prochaine version.
Je vais approfondir le problème de ShowFormScrollBars - j'ai Windows 10, pas autre chose... En plus, je viens de voir que la doc de ShowFormScrollBars n'est pas correcte - le copier/coller n'a pas été corrigé jusqu'au bout. Je vais revoir tout ça.
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: KGF_dll - nouvelles versions Jeu 14 Jan 2021 - 9:49
Je n'arrive pas à faire marcher FormScrollBars. Je vais retirer cette fonction. Voici comment régler le problème, avec les moyens actuels de KGF.dll:
Code:
' test_ShowFormScrollBars.bas
dim res%, SP1%
dll_on "KGF.dll"
memo 10 : top 10,10 : left 10,width_client(0)-20 font_names_load 10
Si tu as plusieurs objets dans la form, ou s'il y a des objets sans handle (ALPHA, ...), alors place-les dans un PANEL et attache le PANEL au ScrollPanel, et le tour est joué.
Marc
Nombre de messages : 2466 Age : 63 Localisation : TOURS (37) Date d'inscription : 17/03/2014
Sujet: Re: KGF_dll - nouvelles versions Jeu 14 Jan 2021 - 15:11
Ok pour tout !
Merci Klaus !
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Sujet: Re: KGF_dll - nouvelles versions Mar 19 Jan 2021 - 14:40
KGF.dll V9.45 du 19/01/2021
Nouveautés: - KGF.ilb: nouvelles icônes 382 à 393 (figures du jeu d'échecs en icônes 16x16) - nouvelle ilb: Chess_48.ilb = 12 icônes 48x48 des figures du jeu d'échecs - nouvel objet: ChessBoard et ses fonctions de support - nouvelles fonctions: CreateChessBoard, SetChessBoardTrace, MoveChessBoardPiece, PopulateChessBoard
Modules modifiés: KGF.dll KGF.chm
La doc est à jour.
Cet objet réalise un plateau de jeu d'echecs, avec toutes les pièces qui vont avec. Les pièces sont jouales en les "tirant" par la souris pour les "lâcher" dans la case cible. Mais ces mouvements sont soumis au contrôle des règles de déplacements des pièces pour un jeu d'échecs. Ma prise des pièces est gérée, les movements non autorisés sont rejetés et la victoire (prise du roi adverse) est détectée. Les blancs commencent, ensuite les couleurs jouent alternativement. On peut choisir les couleurs pour les cases "sombres" et "claires".
Voici le programme de démo, très simple. En fait, tout est géré dans la DLL. A titre d'exemple, un bouton permet de changer la configuration par une configuration imposée et de la jouer - c'est le cas des problèmes d'échecs publiés dans les journaux.
Nouveautés: - ChessBoard: possiblité de jouer en double-plateau synchronisé - nouvel objet: SharedMemory - nouvel objet: BitmapList
Modules modifiés: KGF.dll KGF.chm
La doc est à jour.
Mise à jour majeure !
ChessBoard: On peut maintenant générer le programme en EXE et le lancer deux fois. En déplaçant les fenêtres côte à côte pour qu'elle ne se recouvrent pas, on découvre deux plateaux identiques. Mais ces plateaux sont maintenant synchronisés. La première pièce blanche jouée que n'importe quel plateau affecte la couleur blanche à ce plateau et la couleur noire à l'autre. A partir de ce moment, sur les deux plateaux, on ne peut plus bouger que les pièces de la couleur affectée. Chaque coup joué sur un plateau est automatiquement reporté sur l'autre plateau. Sinon, tout reste inchangé, y compris l'annulation, possible sur chacun des plateaux.
Voici le programme de démo adapté à cette version:
list 1002 : top 1002,10 : left 1002,10 : height 1002,height_client(0)-20 : width 1002,200 on_click 1002,SelectBitmap picture 1003 : top 1003,10 : left 1003,left(1002)+width(1002)+10 width 1003,width_client(0)-left(1003)-10 : height 1003,height(1002) image 1004
form 2000 : hide 2000 : top 2000,top(0)+100 : left 2000,left(0)+100 : width 2000,400 font_name 2000,"Lucida sans Typewriter" alpha 2001 : parent 2001,2000 : left 2001,20 : top 2001,20 : caption 2001,"BmpLibrary - Bitmap Library Utility" font_size 2001,12 alpha 2002 : parent 2002,2000 : left 2002,20 : top 2002,50 : caption 2002,"Author: Klaus" alpha 2003 : parent 2003,2000 : left 2003,20 : top 2003,80 : caption 2003,"Created: 05/02/2021" alpha 2004 : parent 2004,2000 : left 2004,20 : top 2004,110 : caption 2004,"KGF.dll minimum: V09.48 03/02/2021"
dll_on "KGF.dll"
end
close0: if BL%<>0 then BL% = dll_call1("DeleteBitmapList",BL%) return
exit: if BL%<>0 if message_confirmation_yes_no("Library actually open. Discard it ?")<>1 then return BL% = dll_call1("DeleteBitmapList",BL%) end_if terminate
saveas: if BL%=0 then return filter 1000,"Bitmap library file (blb)|*.blb" s$ = file_name$(1000) if s$="_" then return res% = dll_call2("SaveBitmapListToFile",BL%,adr(s$)) if res%=0 ListName$ = s$ modif$ = "" caption 0,"BmpLibrary - "+ListName$ + " "+modif$ + " " + str$(ImageCount%)+" bitmaps" message "Ok" else message "Error" end_if return
close: if BL%=0 then return if modif$="*" if message_confirmation_yes_no("Library is modified. Discard it ?")<>1 then return end_if BL% = dll_call1("DeleteBitmapList",BL%) ImageCount% = 0 modif$ = "" clear 1002 caption 0,"BmpLibrary" return
SharedMemory: Cet objet réalise un de mes vieux rêves; une zone mémoire partagée entre plusieurs programmmes ! Et ce de fçon synchronisée et sécurisée, avec les verrouillages qui vont bien. Le programme de démo montre une zone partagée de 4096 octets (1 page de mémoire virtuelle), dans laquelle je place l'image d'une chaîne de caractères, d'un nombre entier, d'un nombre flottant et du contenu d'un mémo. Un autre mémo montre le "dump" du début le la mémoire partagée. - Générez ce programme en EXE et lancez-le 3 fois. - Déplacez les fenêtres de sorte que les champs soient visibles en même temps. - Puis, fenêtre après fenêtre, dans n'importe quel ordre, cliquez sur le bouton "Connect". On voit que le nombre d'utilisateurs et le contenu de l'adresse 0 change au fur et à mesure. - Lorsque les 3 programmes sont connectés, rentrez des données dans un ou plusieurs champs d'une des 3 fenêtres, puis cliquez sur "Change". On voit que le contenu de la mémoire partagée a changé et que les champs des deux autres fenêtres sont automatiquement mis à jour. - Changez des données dans une autre fenêtre et cliquez sur "Change" de cette fenêtre pour voir, là encore, les changements reportés automatiquement dans les deux autres fenêtres. - Cliquez sur "Disconnext" dans une des fenêtres, on voit que le nombre d'utilisateurs a changé dans les deux autres fenêtres. - Changez le données dans une des deux fenêtres restantes et cliquez sur "Change". L'autre fenêtre est actualisée mais pas la fenêtre déconnectée. - Cliquez sur "Connect" de la fenêtre déconnectée et les données sont actialisées immédiatement.
UserEvent: if SM%=0 then return if USER_EVENT_WPARAM<>hex("12010000") then return if USER_EVENT_LPARAM<>SMID% then return off_user_event res% = dll_call2("GetSharedMemoryArray",SM%,adr(array%)) gosub displayvariables gosub displayarray on_user_event UserEvent return
Ceci ouvre la voie vers une architecture client-serveur. Imaginez un programme Panoramic dont la form 0 ext cachée par HIDE et qui tourne donc en arrière-plan. Il sera lancé en premier, au démarrage de l'ordinateur, par exemple. et il ne s'arrête jamais. C'est le serveur. Les autres programmes partagent a zone mémoire pour lui soumettre des requêtes et reçoivent la réponse également dans la mémoire partagée. Tout le secret réside alors dans le design et l'organisation de l mémoire partagée. Techniquement, tout est là.
BitmapList: Cet objet est similaire à l'objet ImageList, mais il peut contenir des images quelconques, de dimensions différentrs. Voici le programme de démo - un gestionnaire complet de bibliothèque d'images:
list 1002 : top 1002,10 : left 1002,10 : height 1002,height_client(0)-20 : width 1002,200 on_click 1002,SelectBitmap picture 1003 : top 1003,10 : left 1003,left(1002)+width(1002)+10 width 1003,width_client(0)-left(1003)-10 : height 1003,height(1002) image 1004
form 2000 : hide 2000 : top 2000,top(0)+100 : left 2000,left(0)+100 : width 2000,400 font_name 2000,"Lucida sans Typewriter" alpha 2001 : parent 2001,2000 : left 2001,20 : top 2001,20 : caption 2001,"BmpLibrary - Bitmap Library Utility" font_size 2001,12 alpha 2002 : parent 2002,2000 : left 2002,20 : top 2002,50 : caption 2002,"Author: Klaus" alpha 2003 : parent 2003,2000 : left 2003,20 : top 2003,80 : caption 2003,"Created: 05/02/2021" alpha 2004 : parent 2004,2000 : left 2004,20 : top 2004,110 : caption 2004,"KGF.dll minimum: V09.48 03/02/2021"
dll_on "KGF.dll"
end
close0: if BL%<>0 then BL% = dll_call1("DeleteBitmapList",BL%) return
exit: if BL%<>0 if message_confirmation_yes_no("Library actually open. Discard it ?")<>1 then return BL% = dll_call1("DeleteBitmapList",BL%) end_if terminate
saveas: if BL%=0 then return filter 1000,"Bitmap library file (blb)|*.blb" s$ = file_name$(1000) if s$="_" then return res% = dll_call2("SaveBitmapListToFile",BL%,adr(s$)) if res%=0 ListName$ = s$ modif$ = "" caption 0,"BmpLibrary - "+ListName$ + " "+modif$ + " " + str$(ImageCount%)+" bitmaps" message "Ok" else message "Error" end_if return
close: if BL%=0 then return if modif$="*" if message_confirmation_yes_no("Library is modified. Discard it ?")<>1 then return end_if BL% = dll_call1("DeleteBitmapList",BL%) ImageCount% = 0 modif$ = "" clear 1002 caption 0,"BmpLibrary" return
J’ai testé BitmapList (uniquement avec des JPG et des BMP), tout fonctionne bien !
J’ai testé SharedMemory avec 5 exe. Pas de problème, la synchro fonctionne parfaitement, aucun conflit. Connexion, déconnection, reconnexion, mise à jour des données partagées etc, R.A.S.
Il ne me reste plus qu’à essayer ChessBoard.
lepetitmarocain
Nombre de messages : 341 Age : 82 Localisation : Région Parisienne (à mon grand désespoir) Date d'inscription : 04/07/2018
Je pense que tu as tout simplement oublié de cliquer sur le bouton "Connect" après le lancement de chaque programme. Tant que ce clic n'est pas fait, le programme n'est pas connecté sur la mémoire partagée et, évidemment, rien ne se passe.
lepetitmarocain
Nombre de messages : 341 Age : 82 Localisation : Région Parisienne (à mon grand désespoir) Date d'inscription : 04/07/2018
Chez moi, je procède comme suit: - je génère l'exécutable à partir du source du programme de démo, par Panoramc_Editor, menu Fichiers, option Executable. - je lance cet EXE 3 fois, en double-cliquant dessus dans l'explorateur. - je place les 3 fenêtres de sorte à les voir toutes les 3, simultanément - puis, fenêtre par fenêtre, je clique sur le bouton "Connect". Lors du clic sur ce bouton dans la première fenêtre, rien ne se passe dans les deux autres fenêtres, mais celle dont le bouton Connect a été cliqué, montre bien un nombre d'utilisateurs égal à 1, et dans le mémo de gauche contenant le dump du début de la mémoire partagée, la cellule 0 montre bien la valeur 1. - je clique maintenant sur le bouton Connect d'une des deux autres fenêtres. Dans cette deuxième fenêtre, tout comme dans la première, le nombre d'utilisateur s"affiche comme 2, et le dump de la mémoire partagée montre la valeur 2 dans la cellule 0.
Et ainsi de suite. Je ne constate aucun disfonctionnement.
Dis-moi sous quel système tu travailles, quelle version de Windows ?
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
Parfait ! On avance ! Merci à vous deux pour les tests et ces diagnostics.
Il s'agit dont d'un problème de version de Windows.
Je vais regarder si je trouve des différences entre W7 et W10 qui expliqueraient ce qui se passe. Peut-être y arriverai-je avec un effort raisonnable. Cependant, je vous alerte sur la "fin de vie" de W7, plus précisément la fin du support MicroSoft pour W7: https://www.microsoft.com/fr-fr/windows/windows-7-end-of-life-support-information
Donc, si je trouve "prochainement" un moyen de régler ce problème sous W7, je vais le mettre en place.
Peut-être pourrait-on envisager, à moyen terme, de migrer vers un W10 afin de bénéficier du support de MicroSoft ? Les mises à jour de sécurité, ce n'est pas rien...
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
displayarray: clear 100 for i%=0 to 30 s$ = str$(i%*4)+" "+hex$(array%(i%)) item_add 100,s$ next i% return
displayvariables: usercount% = array%(0) caption 11,str$(usercount%) res% = dll_call3("CopyFloatFromIntegerArray",adr(float),adr(array%),1) text 21,str$(float) res% = dll_call3("CopyIntegerFromIntegerArray",adr(integer%),adr(array%),3) text 31,str$(integer%) s$ = GetString$(4) text 41,s$ s$ = GetString$(100) text 51,s$ return
connect: if log%=0 then log% = 1 if log%=1 then file_open_write 1,"SharedMemory_"+str$(handle(0))+".log" SM% = dll_call3("CreateSharedMemory",adr(SMName$),SMID%,1) if log%=1 then file_writeln 1,date$+" "+time$+" "+str$(handle(0))+" connect: CreateSharedMemory: SM%="+str$(SM%) on_user_event UserEvent res% = dll_call2("GetSharedMemoryArray",SM%,adr(array%)) if log%=1 then file_writeln 1,date$+" "+time$+" "+str$(handle(0))+" connect: GetSharedMemoryArray: res%="+str$(res%) gosub displayvariables gosub displayarray inactive 1 active 2 active 3
disconnect: off_user_event active 1 inactive 2 inactive 3 SM% = dll_call1("DeleteSharedMemory",SM%) if log%=1 then file_writeln 1,date$+" "+time$+" "+str$(handle(0))+" close0: DeleteSharedMemory: SM%="+str$(SM%) if log%=1 then file_close 1 log% = 0 usercount% = usercount% - 1 caption 11,str$(usercount%) clear 100 return
close0: off_user_event SM% = dll_call1("DeleteSharedMemory",SM%) if log%=1 then file_writeln 1,date$+" "+time$+" "+str$(handle(0))+" close0: DeleteSharedMemory: SM%="+str$(SM%) if log%=1 then file_close 1 ' res% = dll_call1("SharedMemoryContext",0) res% = dll_call1("KillProcessByHandle",handle(0)) return
UserEvent: if SM%=0 then return if log%=1 then file_writeln 1,date$+" "+time$+" "+str$(handle(0))+" USER_EVENT_WPARAM="+right$("0000000"+hex$(USER_EVENT_LPARAM),8)+" USER_EVENT_LPARAM="+right$("0000000"+hex$(USER_EVENT_WPARAM),8) if USER_EVENT_WPARAM<>hex("12010000") then return if USER_EVENT_LPARAM<>SMID% then return off_user_event res% = dll_call2("GetSharedMemoryArray",SM%,adr(array%)) gosub displayvariables gosub displayarray on_user_event UserEvent return
Tu obtiendra des fichiers logs différents pour chaque programme, avec le handle de la form 0 pour les identifier. Alors, fais la manipulation que j'ai indiquée ci-dessus, puis ferme chaque fenêtre par un clic sur la croix rouge et poste le contenu de ces 3 petits fichiers.
En comparant les heures dans les différents logs, on voit bien que la connexion du deuxième programme à 09:51:15 provoque des USER_EVENT dans le premier programme, qui, à son tour provoque un USER_EVENT dans le deuxième programme. Et idem pour le lancement du troisième qui provque des USER-EVENT dans le premier et le deuxième, qui, à leur tour, provoquent des USER_EVENT dans les autres programmes afin de se synchroniser.
Les logs montrent les actions pour: - activation successive du premier, puis deuxième, et finalement troisième programme - arrêt par la croix rouge des programmes dans le ùême ordre
Voici l'image des 3 programmes. Après ajustement des tailles des fenêtres en remontant le bord inférieur de chaque fenêtre et en déplaçant ces fenêtres. On obtient ceci:
Je te conseille de recharger KGF.dll avant ce test - j'ai changé le code retour de la fonction GetSharedMemoryArray qui retourne maintenant -1 en cas d'erreur et 0 en cas de succès.
Marc
Nombre de messages : 2466 Age : 63 Localisation : TOURS (37) Date d'inscription : 17/03/2014
Bien. Je vois que le mécanisme des messages de synchrnisation fonctionne. C'est l'écriture dans la mémoire partagée qui ne marche pas. Ou, peut-être la relecture... Je vais voir si je trouve des infos sur les réseaux, dans ce contexte.
Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009