Programmation
Icônification et Drag & Drop : ça va être chaud !



Préambule


La mise en icône


On drague ou on droppe ?


RECEVOIR en Drag&Drop :

  1. attendre le message AP_DRAGDROP (63) pour l'EVNT_MULTI de la boucle principale et récupérer certaines valeurs de ce buffer :
    INT{msg_buf%+6} (ou MENU(3)) : handle fenêtre sur laquelle on a déposé quelque chose
    INT{msg_buf%+8} : position X de la souris lors du dépôt
    INT{msg_buf%+10} : position en Y
    INT{msg_buf%+12} : état du clavier (touches Control, Alt, Shift)
    INT{msg_buf%+14} (offset 7) : extension du fichier à ouvrir
    Par un MKI$ avec la valeur de l'offset 7, on obtient un fichier qu'il faut ouvrir :
    U:\PIPE\DRAGDROP.xx où xx est ce MKI$(INT{msg_buf%+14}).

  2. Lorsque ce fichier est ouvert en lecture/écriture avec un GEMDOS, écrivez toujours avec un GEMDOS un mot nul (DD_OK ou 0 sur un WORD). Si vous êtes fâché que que vous voulez rien recevoir, écrivez 1 sur un WORD (DD_NAK).

  3. Puis construisez dans un tampon mémoire de 32 octets, contenant 8 extensions de fichiers de 4 octets chacunes : exemple avec ".TXT", ".DOC", etc. Cette liste correspond aux fichiers que votre application PEUT gérer. Pour des images bitmaps, vu le nombre important de formats, on emploie le format .IMG , pour l'ascii, c'est .TXT ... vous pouvez créer vos propres formats, mais n'oubliez pas que le Drag&Drop est l'échange de données interapplications, donc la compatibilité de fichiers doit être maximum ;-)
    Attention, ARGS (donc sans point) est considéré comme l'échange d'un nom de fichier(s) (ou d'autres arguments). PATH correspond à l'échange d'un chemin et possède un protocole qui s'éloigne de la méthode décrite ici, que malheureusement pour moi, je n'ai pas réussi à comprendre.
    N'oubliez pas qu'on travaille comme en C. Si vous n'avez pas assez d'extensions à donner, remplissez le reste avec des null-bytes. Ecrivez ensuite ce tampon dans le fichier DRAGDROP.xx .

  4. Lisez ensuite un mot (WORD ou INT) sur ce fichier, cette valeur est la taille de l'entête que vous devez lire ensuite. Donc si c'est 0, on abandonne et si vous lisez la valeur 16, lisez ensuite 16 octets. Dans cette entête est contenu  : 4 octets correspondant au format de fichier de votre liste que l'application extérieure a reconnue et est prête à vous envoyer, ensuite un LONG (4 octets) correspondant à la taille des données qui vont être transmises, puis une chaîne de texte terminé par un null-byte (une chaîne en C, quoi :) explicitant ce qui va être échangée (si on ne veut pas expliciter, un null-byte suffit), et enfin le nom d'un fichier qui accompagne les données (null-byte si cela ne correspond pas à un fichier).
    Donc les deux derniers éléments sont facultatifs. On peut s'en passer, mais il faut, si vous envoyez des données en Drag&Drop, les prendre en compte pour la compatibilité.

  5. On analyse donc les éléments de cet entête, et on écrit un WORD sur le fichier d'échange, selon les valeurs :
    ConstanteValeurExplication
    DD_OK0On est prêt à recevoir des données. Après l'écriture de DD_OK dans le fichier, on va pouvoir lire par GEMDOS, toujours sur ce même fichier, les données, la taille de celles-ci étant fournie dans l'entête plus haut.
    Attention, ici, vous lisez des données, mais il faut les stocker dans une zone mémoire que VOUS devez allouer VOUS-MEMES.
    DD_NAK1On est des petits branleurs et on abandonne. Ne pas oublier de fermer le fichier avec un GEMDOS.
    DD_EXT2Le format de fichier ne nous convient pas, et, après l'écriture du mot DD_EXT par notre application, on attend un autre mot (taille d'une nouvelle l'entête), suivi de la nouvelle entête elle-même. Et c'est reparti comme en 14 !
    DD_LEN3Notre application ne peut recevoir autant de données. On attend donc une autre taille d'entête puis son entête.
    Si votre application est un bureau GEM, les valeurs suivantes sont employées
    DD_TRASH4C'est en fait sur votre poubelle qu'on a déposé l'objet du Drag&Drop. On ne fait rien et on ferme le fichier, car c'est à l'application étrangère de détruire ce qu'il a déposé sur la poubelle (ça peut être un morceau de texte, pas nécessairement un fichier entier)
    DD_PRINTER5Même chose : mais pour l'imprimante. On ferme tout et c'est l'application qui a engendré le Drag&Drop d'imprimer elle-même ce qui a été (non)-échangé.
    DD_CLIPBOARD6Idem, mais pour le presse-papier, l'application étrangère doit elle-même sauver dans le clipboard (comme un bête Control+V).

  6. Quoiqu'il se soit passé, on ferme à la fin U:\PIPE\DRADROP.?? .

    Attention les arguments ARGS sont échangés comme des arguments d'une ligne de commande.


ENVOYER en Drag&Drop

    On considère d'abord que vous avez déjà sélectionné ce que vous aller envoyer à une autre application. En général cela se fait à la souris en employant les fonction GRAF_? . Essayer de faire cela élégamment, car il faut que vos Drags et vos Drops soient ergonomiques si vous voulez qu'on les emploie.
    Donc vous avez avec la souris fait un glisser-déposer sur une fenêtre quelconque. Si c'est une des vôtres, c'est à vous de gérer cela, si cette fenêtre n'est pas la vôtre, vous pouvez alors faire un Drag&Drop.
    Utilisez WIND_FIND et WIND_GET(20 WM_OWNER) pour connaître l'ap_id& de l'application dans laquelle vous avez déposer vos trésors. Le Drag&Drop peut alors commencer.

  1. Utilisez la fonction GEMDOS Psignal() (spécial MiNT et comprise par MagiC) qui permet d'ignorer les messages Drag&Drop de réception possibles qui peuvent nous être envoyés (signaux SIGPIPE(13), mais ne me demandez rien, je suis un bleu comme vous dans cette fonction. J'ai trimé pour que cela marche, mais je n'ai par contre pas compris grand chose).

  2. Créez le fichier U:\PIPE\DRADROP.xx où xx est deux caractères ASCII qu'on pourra convertir en WORD. Il faut faire des test avant de créer le fichier pour voir s'il n'existe pas déjà. En général on prend d'abord "AA", puis "AB" sinon, etc. Si la création échoue, on essaye une autre extension. Ce fichier doit être caché, selon le Compendium.

  3. utilisez APPL_WRITE vers l'application dont vous connaissez l'ap_id& (avec ce qu'on a dit plus haut avec WM_OWNER. Le buffer de 16 octets doit être remplie de cette manière :
    Offset (en octets)Contenu (en mot, INT)
    +0AP_DRAGDROP (63)
    +2votre ap_id&
    +40
    +6Handle de la fenêtre où a été déposé les données à échanger
    +8Position en X de la souris à ce moment
    +10Position en Y de la souris
    +12Etat des touches Control, Alternate et Shift à ce moment (utilisation de GRAF_MKSTATE)
    +14le xx, extension du fichier de Drag&Drop, converti en WORD grâce à CVI("xx")

  4. Utiliser ensuite la fonction GEMDOS Fselect() pour attendre une possible réponse (délai de 3 à 4 secondes selon le Compendium).

  5. Si on a eut une réponse avant l'échéance, on lit un mot dans le fichier. Si ce WORD est nul (DD_OK) on continue, si ce dernier est à 1 (DD_NAK), on abandonne.

  6. Si on a lu 0, on lit ensuite 32 octets. Ce petit tampon correspond aux formats de fichiers que l'autre application peut recevoir. si on trouve .TXT , alors on pourra lui envoyer du texte au format ASCII. Idem pour .IMG ou .GEM , etc. En général, 8 types de fichiers suffisent. Si notre application ne veux pas envoyer à ces 8 formats, on peut continuer en renvoyant plus tard le type de format voulu dans l'entête qui va suivre. A l'autre application de s'accorder. Mais en général, les formats échangés sont de type .TXT et ARGS, le reste du tampon étant rempli par des zéros.

  7. On construit ensuite un entête, avec tout d'abord le format voulu (4 octets, exemple .TXT), puis sur un LONG (4 octets) la longueur des données à envoyer, puis une chaîne C décrivant le type de données échangées (ou un null-byte) (exmple : Texte ASCII), et enfin un nom de fichier facultatif (ou un null-byte obligatoirement sinon).
    On regarde combien cela fait en taille (n'oubliez pas de compter les null-bytes avec) et on écrit cette taille en WORD dans le fichier de Drag&Drop, puis tout de suite après l'entête elle-même.

  8. On a ensuite une réponse de l'application réceptrice en lisant un WORD dans le fichier. Ce sont exactement les codes DD_OK, DD_TRASH et cie plus haut ! Mais ici faites attention : on est dans l'autre position, celle de l'envoyeur.

    Dans le cas favorable (DD_OK lu), on écrit dans le fichier les données à envoyer, puis on ferme et (je suppose) on rétablie la fonction Psignal à son état initial.


Ce n'est qu'un au revoir !



Rajah Lone
écrit le 4 Juin 99