Obligement - L'Amiga au maximum

Mardi 27 juin 2017 - 21:06  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Hit Parade
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Moteurs de recherche
 · Pages de liens
 · Constructeurs matériels
 · Matériel
 · Autres sites de matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Développeurs logiciels
 · Logiciels
 · Développeurs de jeux
 · Jeux
 · Autres sites de jeux
 · Scène démo
 · Divers
 · Informatique générale


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Soutien

N'hésitez pas à soutenir le projet Obligement



Contact

David Brunet

Courriel

 


Programmation : Assembleur - copie d'icône
(Article écrit par Frédéric Delacroix et extrait d'Amiga News - octobre 1996)


Lorsqu'on veut doter un fichier d'une icône, deux solutions sont offertes. La première réside en le lourd programme IconEdit, et la seconde consiste à copier le fichier ".info" correspondant à l'icône voulue. Voici une troisième solution.

Pourquoi ?

Pourquoi ne pas se contenter, en effet, de bêtement copier le fichier "Source.info" en "Destination.info" ? Plusieurs raisons à cela. La principale tient au fait que toutes les données sont copiées, y compris - et cela peut être gênant - le type (projet, outil...) de l'icône, les types d'outil, la position... Lorsqu'on veut juste l'image d'une autre icône, il faut utiliser IconEdit.

Quoi ?

Le programme que je vous décris ici n'a en fait pas grand-chose d'original dans sa fonctionnalité, mais il a le mérite de montrer le fonctionnement de plusieurs aspects du système. Il ouvre une fenêtre avec deux gadgets texte et un bouton. Il attend ensuite que l'on dépose une icône sur l'un des deux gadgets textes (source et destination). Le nom de l'icône apparaît alors dans le gadget. Une fois les deux icônes choisies, vous pourrez cliquer sur le bouton "Copy" pour copier l'image de l'icône source dans l'icône destination. Fermez la fenêtre pour quitter le programme.

Comment ?

L'interfaçage entre le programme et le Workbench pour déposer les icônes se fait par la workbench.library et ses AppWindows, dont j'ai déjà parlé dans un article précédent. La copie d'icônes se fait par l'intermédiaire des fonctions GetDiskObjectNew() et PutDiskObject() de l'icon.library, dont l'usage est détaillé dans le listage ci-dessous. Dans la structure DiskObject de destination, on remplace toute la structure Gadget par celle du DiskObject source. Il ne suffit pas de remplacer les images, car les autres champs de la structure Gadget ont leur importance (je soupçonne Kamel d'avoir modifié les GetDiskObject()s de l'icon.library dans son programme NoDraw pour avoir une taille de 0). Un simple CopyMem() fait l'affaire.

Pour ce qui est de la pseudo-interface graphique, elle utilise la gadtools.library. Libre à vous de l'améliorer en utilisant les articles déjà publiés à ce sujet ici même, la place me manquant.

Bogues ?

Un programme si court ne saurait être parfait. Ses défauts sont de ne pas afficher le nom des répertoires dans les gadgets textes, de ne pas pouvoir affecter les icônes sorties sur l'écran du Workbench ou les disques (je vous laisse deviner pourquoi, j'interroge le mois prochain), et bien sûr l'interface graphique assez minable. Vous y remédierez facilement, pour peu que vous vous penchiez de suffisamment près sur le fonctionnement du programme. Pour un assemblage correct, ce programme nécessite les macro-instructions de Hisoft Devpac 3.50, distribué par ADFI.

; IconCopy.s, version 1.0
; nécessite les fichiers de macros de Hisoft Devpac 3.50

    IMPORT  exec,exec
    IMPORT  workbench,icon
    IMPORT  workbench,workbench
    IMPORT  workbench,startup
    IMPORT  intuition,intuition
    IMPORT  libraries,gadtools
    IMPORT  dos,dos
    include HISOFT_DEVPAC:Macro/defines.i
    include HISOFT_DEVPAC:Macro/exec.i

    move.l  4.w,a6
    moveq   #20,d7      ; code de retour
    move.l  a6,Exec.Base
    OPENLIB Intuition,37    ; ouvre les bibliothèques
    move.l  d0,Intuition.Base   ; nécessaires (Kickstart 2.04+)
    beq NoIntuition
    OPENLIB Icon,37
    move.l  d0,Icon.Base
    beq.s   NoIcon
    OPENLIB Workbench,37
    move.l  d0,Workbench.Base
    beq.s   NoWB
    OPENLIB GadTools,37
    move.l  d0,GadTools.Base
    beq.s   NoGadTools
    OPENLIB DOS,37
    move.l  d0,DOS.Base
    beq.s   NoDOS

    bsr.s   OpenWindow  ; initialisation
    beq.s   Exit
    bsr     MainLoop    ; traitement
    bsr     CloseWindow ; libération
    moveq   #0,d7

Exit    move.l  DOS.Base(pc),a1
    CALL    CloseLibrary,Exec.Base
NoDOS   move.l  GadTools.Base(pc),a1
    CALL    CloseLibrary
NoGadTools
    move.l  Workbench.Base(pc),a1
    CALL    CloseLibrary
NoWB    move.l  Icon.Base(pc),a1
    CALL    CloseLibrary
NoIcon  move.l  Intuition.Base(pc),a1
    CALL    CloseLibrary
NoIntuition
    move.l  d7,d0
    rts

OpenWindow  ; (Z=0)Success=OpenWindow()
    PUSH    d0-d2/a0-a1/a6,OpenWindow
    lea     Workbench.Name(pc),a0
    CALL    LockPubScreen,Intuition.Base(pc)
    move.l  d0,a0
    suba.l  a1,a1
    CALL    GetVisualInfoA,GadTools.Base(pc)
    move.l  d0,Screen.VI
    beq     .Fail
    lea     Window.GList(pc),a0
    CALL    CreateContext   ; création du contexte GadTools
    move.l  d0,d2
    beq     .Fail

    moveq   #TEXT_KIND,d0   ; gadget texte Source
    move.l  d2,a0
    lea     Source.NewGad(pc),a1
    move.l  Screen.VI(pc),gng_VisualInfo(a1)
    lea     Source.Tags(pc),a2
    CALL    CreateGadgetA
    move.l  d0,d2
    move.l  d0,Source.Gad
    beq     .Fail

    moveq   #TEXT_KIND,d0   ; gadget texte Destination
    move.l  d2,a0
    lea     Dest.NewGad(pc),a1
    move.l  Screen.VI(pc),gng_VisualInfo(a1)
    lea     Dest.Tags(pc),a2
    CALL    CreateGadgetA
    move.l  d0,d2
    move.l  d0,Dest.Gad
    beq.s   .Fail

    moveq   #BUTTON_KIND,d0 ; bouton de copie
    move.l  d2,a0
    lea     Copy.NewGad(pc),a1
    move.l  Screen.VI(pc),gng_VisualInfo(a1)
    suba.l  a2,a2
    CALL    CreateGadgetA
    move.l  d0,d2
    move.l  d0,Copy.Gad
    beq.s   .Fail

    suba.l  a0,a0   ; ouverture de la fenêtre
    lea     Window.Tags(pc),a1
    CALL    OpenWindowTagList,Intuition.Base(pc)
    move.l  d0,Window.Window
    beq.s   .Fail

    CALL    CreateMsgPort,Exec.Base(pc)
    move.l  d0,AppWindow.Port   ; port de communication avec WB
    beq.s   .Fail

    move.l  Window.Window(pc),a0    ; déclare que notre fenêtre
    move.l  AppWindow.Port(pc),a1   ; est une AppWindow
    suba.l  a2,a2
    CALL    AddAppWindowA,Workbench.Base(pc)
    move.l  d0,Window.AppWindow
    beq.s   .Fail
    moveq   #-1,d0  ; succes
    bra.s   .Ret
.Fail   bsr.s   CleanUpWindow   ; en cas d'erreur: tout libérer
    moveq   #0,d0   ; erreur
.Ret    POP OpenWindow
    rts

CleanUpWindow
    PUSH    d0-d1/a0-a1/a6,CleanUpWindow
    move.l  AppWindow.Port(pc),a0   ; peut être nul
    CALL    DeleteMsgPort,Exec.Base(pc)
    move.l  Window.Window(pc),d0
    beq.s   .NoWin
    move.l  d0,a0
    CALL    CloseWindow,Intuition.Base(pc)
.NoWin  move.l  Window.GList(pc),a0
    CALL    FreeGadgets,GadTools.Base(pc)   ; idem
    move.l  Screen.VI(pc),a0
    CALL    FreeVisualInfo  ; idem
    lea     Workbench.Name(pc),a0
    CALL    UnlockPubScreen,Intuition.Base(pc)  ; idem
    POP     CleanUpWindow
    rts

CloseWindow
    PUSH    d0-d1/a0-a2/a6,CloseWindow
    move.l  Window.AppWindow(pc),a0
    CALL    RemoveAppWindow,Workbench.Base(pc)
    move.l  AppWindow.Port(pc),a2
    move.l  Exec.Base(pc),a6
.Empty  move.l  a2,a0   ; vide le port de communication avec
    CALL    GetMsg  ; le Workbench avant de fermer la fenêtre
    move.l  d0,a1
    move.l  a1,d0
    beq.s   .End
    CALL    ReplyMsg
    bra.s   .Empty
.End    bsr CleanUpWindow
    lea     Source.Gad(pc),a2
    bsr     FreeArg ; libère les ressources éventuellement
    lea     Dest.Gad(pc),a2 ; allouées pour les icônes
    bsr     FreeArg
    POP     CloseWindow
    rts

MainLoop
    move.l  Window.Window(pc),a3
    move.l  wd_UserPort(a3),a2
    move.l  AppWindow.Port(pc),a4
.MainLoop
    moveq   #0,d0
    move.b  MP_SIGBIT(a2),d1    ; signal de la fenêtre
    bset    d1,d0
    move.b  MP_SIGBIT(a4),d1    ; du Workbench
    bset    d1,d0
    CALL    Wait,Exec.Base(pc)
    move.l  d0,d7
    move.b  MP_SIGBIT(a2),d1
    bclr    d1,d7
    beq.s   .TestWB
.WndLoop
    move.l  a2,a0
    CALL    GT_GetIMsg,GadTools.Base(pc)    ; message de la fenêtre?
    move.l  d0,a1
    move.l  a1,d0
    beq.s   .TestWB
    move.l  im_Class(a1),d6
    CALL    GT_ReplyIMsg
    cmp.l   #IDCMP_REFRESHWINDOW,d6
    bne.s   .NoRefresh
    move.l  a3,a0   ; demande de rafraîchissement
    CALL    GT_BeginRefresh ; laisse GadTools bosser
    move.l  a3,a0
    moveq   #1,d0
    CALL    GT_EndRefresh
    bra.s   .WndLoop
.NoRefresh
    cmp.l   #IDCMP_GADGETUP,d6  ; "Copy" actionné?
    bne.s   .NoGadgetUp
    bsr     Copy
    bra.s   .WndLoop
.NoGadgetUp
    cmp.l   #IDCMP_CLOSEWINDOW,d6   ; fermer la fenêtre?
    bne.s   .WndLoop
    rts     ; fin
.TestWB move.b  MP_SIGBIT(a4),d1
    bclr    d1,d7
    beq     MainLoop
.WBLoop move.l  a4,a0
    CALL    GetMsg,Exec.Base(pc)    ; message du WB?
    move.l  d0,a5
    move.l  a5,d0
    beq     .MainLoop
    cmp.w   #AMTYPE_APPWINDOW,am_Type(a5)
    bne.s   .ReplyWB
    cmp.l   #1,am_NumArgs(a5)
    blo.s   .ReplyWB
    move.w  am_MouseY(a5),d0    ; ordonnée du pointeur
    cmp.w   #YLIMIT,d0
    blo.s   .SourceGad
    lea     Dest.Gad(pc),a0 ; sur gadget "Destination"
    bsr.s   CopyWBArg
    bsr     UpdateTextGad
    bra.s   .ReplyWB
.SourceGad
    lea     Source.Gad(pc),a0   ; sur gadget "Source"
    bsr.s   CopyWBArg   ; copie de l'argument
    bsr     UpdateTextGad   ; (répertoire et nom)
.ReplyWB
    move.l  a5,a1
    CALL    ReplyMsg,Exec.Base(pc)
    bra.s   .WBLoop

CopyWBArg   ; CopyWBArg(Storage,AppMessage)(A0,A5)
    PUSH    d0-d1/a0-a3/a6,CopyWBArg
    move.l  a0,a2
    bsr.s   FreeArg ; libère le précédent
    move.l  am_ArgList(a5),a3
    move.l  wa_Lock(a3),d1
    CALL    DupLock,DOS.Base(pc)    ; copie le Lock du répertoire
    move.l  d0,4(a2)
    beq.s   .Fail
    move.l  wa_Name(a3),d0
    move.l  d0,a0
.Len    tst.b   (a0)+   ; et le nom (en allouant de la mem)
    bne.s   .Len
    sub.l   a0,d0
    neg.l   d0  ; longueur du nom +1
    move.l  #MEMF_PUBLIC!MEMF_CLEAR,d1
    CALL    AllocVec,Exec.Base(pc)
    move.l  d0,8(a2)
    bne.s   .CopyName
    bsr.s   FreeArg
    bra.s   .Fail
.CopyName
    move.l  wa_Name(a3),a0
    move.l  8(a2),a1
.Cpy    move.b  (a0)+,(a1)+
    bne.s   .Cpy
.Fail   POP CopyWBArg
    rts

FreeArg ; FreeArg(Arg)(A2)
    PUSH    d0-d1/a0-a2/a6,FreeArg
    move.l  8(a2),d0    ; name
    beq.s   .NoMem
    move.l  d0,a1
    CALL    FreeVec,Exec.Base(pc)
    clr.l   8(a2)
.NoMem  move.l  4(a2),d1    ; lock
    beq.s   .NoLock
    CALL    UnLock,DOS.Base(pc)
    clr.l   4(a2)
.NoLock POP FreeArg
    rts

UpdateTextGad   ; UpdateTextGad(Storage)(A0)
    PUSH    d0-d1/a0-a4/a6,UpdateTextGad
    move.l  a0,a4   ; mise à jour du gadget Texte
    move.l  (a4),a0
    move.l  Window.Window(pc),a1
    suba.l  a2,a2
    clr.l   -(sp)   ; TAG_DONE
    move.l  8(a4),-(sp)
    pea     GTTX_Text
    move.l  sp,a3
    CALL    GT_SetGadgetAttrsA,GadTools.Base(pc)
    add.l   #12,sp
    POP     UpdateTextGad
    rts

Copy    PUSH    d0-d1/d7/a0-a1/a4-a6,Copy
    tst.l   Source.Gad+8    ; source sélectionnée?
    beq.s   .Error
    tst.l   Dest.Gad+8  ; dest sélectionnée?
    beq.s   .Error
    move.l  Source.Gad+4(pc),d1 ; rep source
    CALL    CurrentDir,DOS.Base(pc)
    move.l  d0,d7   ; ancien rep
    move.l  Source.Gad+8(pc),a0
    CALL    GetDiskObjectNew,Icon.Base(pc)
    move.l  d0,a4   ; icône source
    move.l  a4,d0
    beq.s   .DirBack
    move.l  Dest.Gad+4(pc),d1   ; rep destination
    CALL    CurrentDir,DOS.Base(pc)
    move.l  Dest.Gad+8(pc),a0
    CALL    GetDiskObjectNew,Icon.Base(pc)
    move.l  d0,a5   ; icône destination
    move.l  a5,d0
    beq.s   .FreeSource
    lea     do_Gadget(a4),a0    ; Gadget Source
    lea     do_Gadget(a5),a1    ; Gadget Destination
    move.l  #gg_SIZEOF,d0   ; taille de la zone à copier
    CALL    CopyMem,Exec.Base(pc)
    move.l  Dest.Gad+8(pc),a0
    move.l  a5,a1
    CALL    PutDiskObject,Icon.Base(pc) ; écrit la nouvelle icône

    move.l  a5,a0   ; libère la destination
    CALL    FreeDiskObject
.FreeSource
    move.l  a4,a0   ; libère la source
    CALL    FreeDiskObject
.DirBack
    move.l  d7,d1   ; revient au répertoire précédent
    CALL    CurrentDir,DOS.Base(pc)
.Error  POP Copy
    rts

Exec.Base           Aptr    0
Intuition.Base      Aptr    0
Workbench.Base      Aptr    0
Icon.Base           Aptr    0
GadTools.Base       Aptr    0
DOS.Base            Aptr    0
Screen.VI           Aptr    0
Window.Window       Aptr    0
AppWindow.Port      Aptr    0
Window.AppWindow    Aptr    0

Source.Gad          Aptr    0   ; petite structure pour CopyArg()
    Bptr    0   ; lock
    Aptr    0   ; nom, alloué par AllocVec()

Dest.Gad    Aptr    0   ; idem
    Bptr    0
    Aptr    0

Copy.Gad    Aptr    0

Source.NewGad
    dc.w    10,20,200,10
    dc.l    Source.Name,Topaz.Font
    dc.w    0
    dc.l    PLACETEXT_BELOW,0,0

Dest.NewGad
    dc.w    10,60,200,10
    dc.l    Dest.Name,Topaz.Font
    dc.w    0
    dc.l    PLACETEXT_BELOW,0,0

YLIMIT  EQU 59

Copy.NewGad
    dc.w    70,100,80,10
    dc.l    Copy.Name,Topaz.Font
    dc.w    0
    dc.l    PLACETEXT_IN,0,0

Source.Tags
Dest.Tags
    dc.l    GTTX_Border,1
    dc.l    TAG_DONE

Topaz.Font
    Aptr    Topaz.Name
    Uword   8
    Ubyte   0
    Ubyte   0

    INTNAME
    WORKBENCH_NAME
    ICONNAME
    GADTOOLSNAME
    DOSNAME

Window.Tags
    dc.l    WA_Width,220
    dc.l    WA_Height,120
IDCMP=BUTTONIDCMP!TEXTIDCMP!IDCMP_REFRESHWINDOW!IDCMP_CLOSEWINDOW
    dc.l    WA_IDCMP,IDCMP
    dc.l    WA_Flags,WFLG_DRAGBAR!WFLG_DEPTHGADGET!WFLG_CLOSEGADGET
    dc.l    WA_Gadgets
Window.GList    Aptr    0
    dc.l    WA_Title,Window.Title
    dc.l    WA_ScreenTitle,Window.Title
    dc.l    WA_PubScreenName,Workbench.Name
    dc.l    TAG_DONE

Workbench.Name  dc.b    "Workbench",0
Source.Name     dc.b    "Source",0
Dest.Name       dc.b    "Destination",0
Copy.Name       dc.b    "Copy",0
Topaz.Name      dc.b    "topaz.font",0
Window.Title    dc.b    "IconCopy",0


[Retour en haut] / [Retour aux articles] [Article précédent] / [Article suivant]