Affichage multiples de texte ou d'images

Description

Affichage successifs par simple clic de divers fichiers texte ou d'immages dans des onglets différents.

Source / Exemple :


;Semainier.asm  
    .586
      .model flat, stdcall
      option casemap :none   ; case sensitive

;*********************************************

      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\comCtl32.inc
      include \masm32\include\shell32.inc
      include \masm32\include\gdi32.inc 
      include \masm32\include\masm32.inc 
      include \masm32\include\ole32.inc
      include \masm32\include\oleaut32.inc                      

      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\comCtl32.lib
      includelib \masm32\lib\shell32.lib
      includelib \masm32\lib\gdi32.lib 
      includelib \masm32\lib\masm32.lib 
      includelib \masm32\lib\ole32.lib
      includelib \masm32\lib\oleaut32.lib                      

;********************************
;      MACROS     
;********************************

      szText MACRO Name, Text:VARARG
        LOCAL lbl
          jmp lbl
            Name db Text,0
          lbl:
        ENDM

      m2m MACRO M1, M2
        push M2
        pop  M1
      ENDM

      return MACRO arg
        mov eax, arg
        ret
      ENDM
 
;**********************************
;          PROTO
;***********************************
   Ed1Proc3    PROTO :DWORD,:DWORD,:DWORD,:DWORD
   Charge      PROTO :DWORD,:DWORD
   DlgProc     PROTO :DWORD,:DWORD,:DWORD,:DWORD 
   Child1Proc  PROTO :DWORD,:DWORD,:DWORD,:DWORD
   DlgProc1    PROTO :DWORD,:DWORD,:DWORD,:DWORD 
   PainProc    PROTO :DWORD      

    .data
      Titre  db "Le bouton (en bas à gauche) va charger un nouveau texte.",13,10
             db "Le texte  prévu à l'origine ne sera affiché qu'a la prochaine sélection de l'onglet",0
      Titre1 db "Le bouton du bas termine l'application. Si vous cliquez sur lui ..... Salut!!!",0
      Titre2 db "Le bouton3 va charger le fichier source de cette application",0 
      Titre3 db "Voici le Copyright",0
      lun  db "Lundi",0
      mar  db "Mardi",0
      mer  db "Mercredi",0
      jeu  db "Jeudi",0
      ven  db "Vendredi",0
      sam  db "Samedi",0
      dim  db "Dimanche",0
      Child1Name db "IDD_Child1",0
      NomFic1 db "LisezMoi.txt",0
      NomFic2 db "Semainier.rc",0
      NomFic3 db "Semainier.asm",0
      NomFic4 db "errR.txt",0
      NomFic5 db "errL.txt",0
      NomFic6 db "errC.txt",0 
      NomFic7 db "disasm.txt",0
      Pas2Fic db "Le Fichier n'existe pas ou le chemin est incorrect.",0
  
;*************************************
    .data?
      
      hInstance    dd ?
      hEdit        dd ?
      Handles LABEL DWORD
      hBtn1        dd ? 
      hBtn2        dd ?
      hBtn3        dd ?
      hBtn4        dd ?
      hBtn5        dd ?
      hBtn6        dd ?
      hBtn7        dd ? 
      hBmp         dd ?
      hwndTab      dd ?
      TabIndex     dd ? 
      Child1       dd ? 
      handle1      dd ?
      hIcon        dd ?
      hFile        dd ?
      hMem         dd ?
      pMem         dd ?
      NbLus        dd ?
      TabCtrlItem  TC_ITEM <?>

;*************************************
  .const
    IDD_DIALOG1 equ  101  
    IDC_TAB1    equ 1001
    IDC_BTN1    equ 1002
    IDC_BTN2    equ 1003
    IDC_BTN3    equ 1004
    IDC_BTN4    equ 1006
    IDC_BTN5    equ 1007
    IDC_BTN6    equ 1008
    IDC_BTN7    equ 1009
  
;*********************************************
    .code
;*********************************************
    start:

    invoke GetModuleHandle,NULL
    mov hInstance,eax 
    invoke InitCommonControls
    invoke DialogBoxParam,hInstance,101,NULL,Addr DlgProc,NULL 
Sortie::            
    invoke ExitProcess,0

;*****************************************  
DlgProc proc hWin :DWORD,uMsg :DWORD,wParam :DWORD, lParam :DWORD

   .IF uMsg == WM_INITDIALOG

;**********************************************
;             Récupérer le handle de TabControl
;**********************************************
      invoke GetDlgItem,hWin,IDC_TAB1
      mov hwndTab,eax

;**********************************************************************
;             Placer le texte dans l'onglet et l'onglet dans TabControl
; 	          ATTENTION : LES INDEX COMMENCENT TOUJOURS à Zéro !!
;**********************************************************************
      mov TabCtrlItem.imask,TCIF_TEXT
      mov TabCtrlItem.pszText,offset lun
      invoke SendMessage,hwndTab,TCM_INSERTITEM,0,offset TabCtrlItem

;*************************************************
;             Idem pour chaque jour de la semaine
;*************************************************
      mov TabCtrlItem.imask,TCIF_TEXT
      mov TabCtrlItem.pszText,offset mar
      invoke SendMessage,hwndTab,TCM_INSERTITEM,1,offset TabCtrlItem
    
      mov TabCtrlItem.imask,TCIF_TEXT
      mov TabCtrlItem.pszText,offset mer
      invoke SendMessage,hwndTab,TCM_INSERTITEM,2,offset TabCtrlItem 
    
      mov TabCtrlItem.imask,TCIF_TEXT
      mov TabCtrlItem.pszText,offset jeu
      invoke SendMessage,hwndTab,TCM_INSERTITEM,3,offset TabCtrlItem 
    
      mov TabCtrlItem.imask,TCIF_TEXT
      mov TabCtrlItem.pszText,offset ven
      invoke SendMessage,hwndTab,TCM_INSERTITEM,4,offset TabCtrlItem 
    
      mov TabCtrlItem.imask,TCIF_TEXT
      mov TabCtrlItem.pszText,offset sam
      invoke SendMessage,hwndTab,TCM_INSERTITEM,5,offset TabCtrlItem 
    
      mov TabCtrlItem.imask,TCIF_TEXT
      mov TabCtrlItem.pszText,offset dim
      invoke SendMessage,hwndTab,TCM_INSERTITEM,6,offset TabCtrlItem 

;*****************************************************************
;             Création des onglets et de la procédure rattachée
;*****************************************************************

      invoke CreateDialogParam,hInstance,addr Child1Name,hwndTab,addr Child1Proc,0
      mov Child1,eax

;********************************************
;        Récupération des handles des boutons
;********************************************

      invoke  GetDlgItem,hWin,IDC_BTN1
      mov hBtn1,eax

      invoke  GetDlgItem,hWin,IDC_BTN2
      mov hBtn2,eax

      invoke  GetDlgItem,hWin,IDC_BTN3
      mov hBtn3,eax

      invoke  GetDlgItem,hWin,IDC_BTN4
      mov hBtn4,eax

      invoke  GetDlgItem,hWin,IDC_BTN5
      mov hBtn5,eax

      invoke  GetDlgItem,hWin,IDC_BTN6
      mov hBtn6,eax

      invoke  GetDlgItem,hWin,IDC_BTN7
      mov hBtn7,eax

;*********************************************************
; Montrer le bouton1 et l'onglet1 et cacher tout le reste.
;*********************************************************

      invoke ShowWindow,hBtn1,SW_SHOW
      invoke UpdateWindow,hBtn1 
      invoke ShowWindow,hBtn2,SW_HIDE
      invoke ShowWindow,hBtn3,SW_HIDE
      invoke ShowWindow,hBtn4,SW_HIDE
      invoke ShowWindow,hBtn5,SW_HIDE
      invoke ShowWindow,hBtn6,SW_HIDE
      invoke ShowWindow,hBtn7,SW_HIDE
      INVOKE ShowWindow,Child1,SW_SHOWDEFAULT

   .ELSEIF uMsg == WM_NOTIFY
      .if wParam == IDC_TAB1;;;       Si le message est émis par Tab :
         mov eax,lParam;;;            Récupérer le 2ème paramètre.
         mov eax,(NMHDR ptr[eax]).code;;;  Commande correspondante ==> eax 
         cmp eax,TCN_SELCHANGE  ;;; On change ?  
         jz ChangeTab           ;;; oui
         jnz NeChangePas        ;;; non

ChangeTab:
;***************************************************
; Récuperer l'adresse du bouton visible actuellement
; et le cacher,demander l'index de l'onglet qui vient
; d'être sélectionné.
;***************************************************

            mov ebx,TabIndex
            mov eax,[Handles+ebx*4]
            invoke ShowWindow,eax,SW_HIDE
            invoke SendMessage,hwndTab,TCM_GETCURSEL,0,0
            mov TabIndex,eax

            .if TabIndex == 0
;*****************************************************
; Et si c'est le 0 : mettre l'onglet en lecture seule, 
; Charger le 1er fichier et montrer le bouton1.
; WINDOWS XP réclame le rafraichissement de l'onglet
; mais ne demande pas qu'il soit montré !!
;*****************************************************

               invoke SendMessage,handle1,EM_SETREADONLY,TRUE,NULL
               invoke Charge,addr NomFic4,handle1
               invoke UpdateWindow,handle1
               invoke ShowWindow,hBtn1,SW_SHOW
               invoke UpdateWindow,hBtn1
;;;               INVOKE ShowWindow,Child1,SW_SHOWDEFAULT
               invoke UpdateWindow,Child1

;***************************************************************************************
; Même opération pour les suivants,le contenu de l'onglet sera chargé lors de sa  
; sélection,il pourra être changé par le bouton correspondant et éventuellement,
; comme ci-dessus, revenir au 1er contenu chaque fois que l'onglet sera appelé.
;***************************************************************************************
            .elseif TabIndex == 1
;*******************************************************************************
; Comme l'éditeur est identique pour tous les jours,si il a été mis en écriture,
; même une seule fois, il faut le remettre en lecture seule a chaque sélection.
; ici on affiche toujours le même message,puisque le bouton sert a quitter.
;*******************************************************************************

               invoke SendMessage,handle1,EM_SETREADONLY,TRUE,NULL
               invoke SendMessage,handle1,WM_SETTEXT,NULL,addr Titre1
               invoke ShowWindow,hBtn2,SW_SHOW
               invoke UpdateWindow,hBtn2
;;;               INVOKE ShowWindow,Child1,SW_SHOWDEFAULT
               invoke UpdateWindow,Child1
 

            .elseif TabIndex == 2
               invoke SendMessage,handle1,EM_SETREADONLY,TRUE,NULL
               invoke Charge,addr NomFic2,handle1; ici retour a chaque changement.
               invoke ShowWindow,hBtn3,SW_SHOW
               invoke UpdateWindow,hBtn3
;;;               INVOKE ShowWindow,Child1,SW_SHOWDEFAULT
               invoke UpdateWindow,Child1

            .elseif TabIndex == 3
               invoke SendMessage,handle1,EM_SETREADONLY,TRUE,NULL
               invoke Charge,addr NomFic1,handle1
               invoke ShowWindow,hBtn4,SW_SHOW
               invoke UpdateWindow,hBtn4
;;;               INVOKE ShowWindow,Child1,SW_SHOWDEFAULT
               invoke UpdateWindow,Child1

            .elseif TabIndex == 4
               invoke SendMessage,handle1,EM_SETREADONLY,TRUE,NULL
               invoke Charge,addr NomFic3,handle1
               invoke ShowWindow,hBtn5,SW_SHOW
               invoke UpdateWindow,hBtn5
;;;               INVOKE ShowWindow,Child1,SW_SHOWDEFAULT
               invoke UpdateWindow,Child1

            .elseif TabIndex == 5
;*************************************************************
; écriture possible ce jour là :                         FALSE
;                                                          V
;************************************************************* 
               invoke SendMessage,handle1,EM_SETREADONLY,FALSE,NULL               
               invoke Charge,addr NomFic6,handle1
               invoke ShowWindow,hBtn6,SW_SHOW
               invoke UpdateWindow,hBtn6
;;;               INVOKE ShowWindow,Child1,SW_SHOWDEFAULT
               invoke UpdateWindow,Child1

            .elseif TabIndex == 6  
               invoke SendMessage,handle1,EM_SETREADONLY,TRUE,NULL
               invoke ShowWindow,hBtn7,SW_SHOW
               invoke UpdateWindow,hBtn7
               invoke Charge,addr NomFic7,handle1
;;;               INVOKE ShowWindow,Child1,SW_SHOWDEFAULT
               invoke UpdateWindow,Child1
           
            .endif
NeChangePas:
      .endif

   .ELSEIF uMsg == WM_COMMAND
      mov eax,wParam
      mov edx,eax
      shr edx,16
      and eax,0FFFFh
      .if edx == BN_CLICKED
         .if eax == IDC_BTN1
            invoke Charge,addr NomFic3,handle1; change le contenu de l'onglet1.
            invoke UpdateWindow,Child1
            ret
         .elseif eax == IDC_BTN2
            invoke EndDialog,hWin,0 ; ici on fout le camp !!.

         .elseif eax == IDC_BTN3
            invoke Charge,addr NomFic7,handle1; et la, on change, tout est possible.
            invoke UpdateWindow,Child1
            ret
            
         .elseif eax == IDC_BTN4;; et ici on ne fait rien.
;*********************************************
; créer la boite de dialogue pour copyright.
; et rafraichir l'affichage précédent lorsque
; l'on quitte le copyright.
;*********************************************
            invoke DialogBoxParam,hInstance,9,NULL,addr DlgProc1,NULL 
            invoke UpdateWindow,Child1            
            ret
            
         .elseif eax == IDC_BTN5;;
            invoke Charge,addr NomFic2,handle1
            invoke UpdateWindow,Child1

         .elseif eax == IDC_BTN6;; on remet en lecture seule.
            invoke SendMessage,handle1,EM_SETREADONLY,TRUE,NULL
            invoke Charge,addr NomFic5,handle1
            invoke UpdateWindow,Child1              

         .elseif eax == IDC_BTN7;;
            invoke Charge,addr NomFic1,handle1
            invoke UpdateWindow,Child1
         .endif
      .endif
   .ELSEIF uMsg == WM_CLOSE
      invoke EndDialog,hWin,0
   .ELSE
      mov eax,FALSE
      ret
   .ENDIF
   mov eax,TRUE
   ret
DlgProc endp     
  
;******************************************

Child1Proc proc hWnd1 :DWORD,uMsg :DWORD,wParam :DWORD,lPARAM :DWORD

   .IF uMsg == WM_INITDIALOG

;********************************
; on cherche le handle de l'édit.
;********************************

      invoke GetDlgItem,hWnd1,3615
      mov handle1,eax

;*******************************************************************************
; Mise de l'onglet en lecture seule. (pas obligatoire,chacun fait ce qu'il veut)
;*******************************************************************************

      invoke SendMessage,handle1,EM_SETREADONLY,TRUE,NULL

;***********************************************************************************
; Chargement du contenu original : invoke Charge,addr NomFic4,handle1 ou alors
; on peut y inscrire un message: Il va remplacer le contenu précédent qui ne sera vu
; qu'a la 2ème sélection de l'onglet.
;***********************************************************************************

      invoke SendMessage,handle1,WM_SETTEXT,NULL,addr Titre   
   .ENDIF
   ret

Child1Proc endp   

;*****************************************  
  
Charge proc Nom :DWORD,Editeur :DWORD

   invoke CreateFile,Nom,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
                     FILE_ATTRIBUTE_ARCHIVE,NULL
   .IF eax == INVALID_HANDLE_VALUE
      invoke SendMessage,Editeur,WM_SETTEXT,NULL,addr Pas2Fic

   .ELSE
      mov hFile,eax
      invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,65535
      mov hMem,eax
      invoke GlobalLock,hMem
      mov pMem,eax
      invoke ReadFile,hFile,pMem,65534,addr NbLus,NULL
      invoke SendMessage,Editeur,WM_SETTEXT,NULL,pMem
      invoke CloseHandle,hFile
      invoke GlobalUnlock,pMem
      invoke GlobalFree,hMem
   .ENDIF
   ret
Charge endp

;***************************************** 

 DlgProc1 proc hWnd3 :DWORD,uMsg :DWORD,wParam :DWORD,lParam :DWORD

   .IF uMsg == WM_INITDIALOG
;***********************************************************************************
; Placer l'icone (Information) dans la barre de titre du controle de Copyright,
; Créer le bouton qui supportera l'image,charger l'image et la placer sur le bouton.
;***********************************************************************************

      invoke LoadIcon,NULL,IDI_ASTERISK
      invoke SendMessage,hWnd3,WM_SETICON,1,eax
      invoke SetWindowText,hWnd3,addr Titre3

;**************************************************
; Pour un Bitmap : utilise IconButton, pas PainProc
;**************************************************
;      invoke IconButton,hWnd3,0,0,330,210,400
;      invoke LoadBitmap,hInstance,10
;      invoke SendMessage,hBtn,BM_SETIMAGE,0,eax

;************************************************
; Pour un .JPG : utilise PainProc, pas IconButton
;************************************************
      invoke BitmapFromResource,hInstance,2000
      mov hBmp,eax

   .ELSEIF uMsg == WM_PAINT
      invoke PainProc,hWnd3

   .ELSEIF uMsg == WM_COMMAND
      .if wParam == IDCANCEL
         invoke EndDialog,hWnd3,0
      .endif

   .ELSEIF uMsg == WM_CLOSE
      invoke EndDialog,hWnd3,0

   .ENDIF
   xor eax,eax
   ret
DlgProc1 endp

;*****************************************  
; 
;******************************************
;Procédure utilisée si il s'agit d'un .JPG
;******************************************
PainProc proc hWnd3 :DWORD

LOCAL hDC:DWORD,hOld :DWORD  
LOCAL memDC :DWORD,ps :PAINTSTRUCT

    invoke BeginPaint,hWnd3,addr ps
    mov hDC,eax
    invoke CreateCompatibleDC,hDC
    mov memDC,eax
    invoke SelectObject,memDC,hBmp
    mov hOld,eax
    invoke BitBlt,hDC,4,4,320,200,memDC,0,0,SRCCOPY
    invoke SelectObject,hDC,hOld
    invoke DeleteDC,memDC
    invoke EndPaint,hWnd3,addr ps
    ret

PainProc endp

;***************************************** 

;***************************************** 
    end start
;******************************************

; Semainier.rc
#include "\masm32\include\resource.h"

#define IDD_DIALOG1  101
#define IDC_TAB1    1001
#define IDC_BTN1    1002
#define IDC_BTN2    1003 
#define IDC_BTN3    1004
#define IDC_BTN4    1006
#define IDC_BTN5    1007
#define IDC_BTN6    1008 
#define IDC_BTN7    1009
#define IDC_EDT1    1005

500 ICON DISCARDABLE "icone29.ico" 

;**********************************************************************************;
; ATTENTION : tout changement de fonte (taille ou type) dans un des deux controles ;
;             entraine une modification des dimensions de la table.                ;
;**********************************************************************************;

IDD_DIALOG1 DIALOGEX  0,0,340,250
;;;;;;;;;;;;; RSRC.rc de essai.29;;;;;;;;;;;;;;

STYLE DS_CENTER | WS_SYSMENU | WS_VISIBLE |WS_CAPTION | WS_MINIMIZEBOX | WS_OVERLAPPED 

CAPTION "Tab Control"

FONT 10,"Courier new",0,0
 
BEGIN
   CONTROL "",IDC_TAB1,"SysTabControl32",NOT 0x00820000 | 0x50018000,6,1,325,231,0x00000000          
   PUSHBUTTON "Change-L",IDC_BTN1,6,234,50,15,0, ,0
   PUSHBUTTON "&Quitte",IDC_BTN2,51,234,50,15,0, ,0
   PUSHBUTTON "Change-Me",IDC_BTN3,96,234,50,15, ,0 
   PUSHBUTTON "Copyright",IDC_BTN4,141,234,50,15,0, ,0
   PUSHBUTTON "Change-V",IDC_BTN5,186,234,50,15,0, ,0
   PUSHBUTTON "Change-S",IDC_BTN6,231,234,50,15,0, ,0
   PUSHBUTTON "Change-D",IDC_BTN7,278,234,50,15,0, ,0

END

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

IDD_CHILD1 DIALOG 2,15,322,266
STYLE WS_CHILD
FONT 10, "Courier"
{
 EDITTEXT 3615,2,2,316,261,WS_BORDER | WS_GROUP | WS_VSCROLL | ES_MULTILINE
} 
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
;   10 BITMAP MOVEABLE PURE LOADONCALL DISCARDABLE "\essai28.bmp"

    2000 IMAGE DISCARDABLE "bd015.jpg"

    9 DIALOGEX MOVEABLE IMPURE LOADONCALL DISCARDABLE 50,50,165,185

        STYLE DS_CENTER | WS_SYSMENU | WS_OVERLAPPED |WS_VISIBLE |WS_CAPTION | DS_MODALFRAME | DS_3DLOOK

        CAPTION "  "

        FONT 10,"Courier new",0,1

 
        BEGIN
            CTEXT "Copyright © 2004\nJe sais,ça date un peu,mais\nje l'avais oublié dans un coin de l'ordinateur\net je viens de le retrouver et de le compléter.",0,10,105,140,70
            PUSHBUTTON "Quitte",IDCANCEL,58,170,50,13,0, ,0 
        END
;€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
;«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»

Conclusion :


Simple amusement qui pourrait tout de même être utile à certains.
Par exemple pour afficher le menu de la semaine ou encore un emploi du temps.
Le nombre d'onglets n'est limité que par la surface d'écran dont on dispose.
A partir de ce projet élémentaire diverses variations sont possibles.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.