Accueil > > > SCREENMATE BOULINATOR
SCREENMATE BOULINATOR
Information sur la source
Description
Un utilisateur, une balle, un bureau et des rebonds : une recette simple pour un programme pas compliqué ! Boulinator est une application gadget parfaitement inutile… Mais il me fallait une idée-support pour m’essayer à l’assembleur Win32. Voilà qui est fait !
Pour information : si vous décider de lancer ce petit programme, sachez qu’une icône va s’ajouter en bas à droite dans la barre des tâches, ce qui vous permet d’accéder à un menu à tout moment. Avec un clic droit sur la balle vous aurez le même résultat. Pour le reste : cliquez gauche sur la balle, déplacez la souris et lâchez tout !
Dans ce code vous trouverez une touche de « région », un soupçon de « thread » et une larme de « floating point ».
Tout ça en assembleur MASM32.
Puisant régulièrement dans les sources de www.asmfr.fr pour apprendre les rudiments de la programmation Win32, il m’a semblé correct d’y déposer une humble participation. Voici donc Boulinator, un inoffensif petit ScreenMate.
Remarques, commentaires et optimisations bienvenu !
mov eax, salut_!
mov a_tous,eax
Source
- Title BOULINATOR Version MASM32
-
- .486
- .model flat, stdcall
- option casemap :none
-
- include \masm32\include\windows.inc
- include \masm32\include\masm32.inc
- include \masm32\include\gdi32.inc
- include \masm32\include\user32.inc
- include \masm32\include\kernel32.inc
- include \masm32\include\shell32.inc
- include \masm32\include\winmm.inc
-
- includelib \masm32\lib\masm32.lib
- includelib \masm32\lib\gdi32.lib
- includelib \masm32\lib\user32.lib
- includelib \masm32\lib\kernel32.lib
- includelib \masm32\lib\shell32.lib
- includelib \masm32\lib\winmm.lib
-
- WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
- InfoDlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
- ParamDlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
- ErrMsg PROTO :DWORD,:DWORD
-
- .const
-
- ID_icon equ 20
- ID_bonk equ 30
- IDR_MENU equ 10000
- IDM_stopper equ 10001
- IDM_continuer equ 10002
- IDM_apropos equ 10003
- IDM_quitter equ 10004
- IDM_parametre equ 10005
- DlgInfo equ 1000
- IDC_BTN1 equ 1001
- DlgParam equ 2000
- IDC_vitesse equ 2001
- IDC_rebond equ 2002
- IDC_gravit equ 2003
- IDC_diam equ 2004
- IDC_son equ 2005
- IDC_annuler equ 2006
- IDC_ok equ 2007
- IDC_textson equ 2018
- THREADMSG equ WM_USER+1
- ICONMSG equ WM_USER+2
-
- .data
-
- ClassName db "Boulinator",0
- AppName db "Boulinator",0
- szvitesse db "La vitesse doit être comprise entre 0 et %u ",0
- szrebond db "Le rebond doit être compris entre 0 et %u ",0
- szgravit db "La gravité doit être comprise entre 0 et %u ",0
- szdiam db "Le diamètre doit être compris entre 5 et %u ",0
- szon db "on",0
- szoff db "off",0
- dragflag dd 0
- threadflag dd 0
- stopflag dd 0
- sonflag dd 1
- valpause dd 10
- diam dd 35
- fposx REAL8 0.0
- fposy REAL8 0.0
- vectx REAL8 0.0
- vecty REAL8 0.0
- rebond REAL8 0.94
- frotte REAL8 0.97
- gravit REAL8 2.0
- ajust REAL8 0.4
- cent REAL8 100.0
- dix REAL8 10.0
-
- .data?
-
- n NOTIFYICONDATA <>
- hInstance HINSTANCE ?
- hwnd HWND ?
- hicon HWND ?
- hmenu HWND ?
- hthread HWND ?
- maxx dd ?
- maxy dd ?
- posx dd ?
- posy dd ?
- IDthread dd ?
- sourx1 dd ?
- soury1 dd ?
- sourx2 dd ?
- soury2 dd ?
- xdiff dd ?
- ydiff dd ?
- vectxinit dd ?
- vectyinit dd ?
- oldx1 dd ?
- oldx2 dd ?
- oldx3 dd ?
- oldy1 dd ?
- oldy2 dd ?
- oldy3 dd ?
-
- .code
-
- start:
-
- invoke GetModuleHandle,NULL
- mov hInstance,eax
- invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT
- invoke ExitProcess,eax
-
- WinMain PROC hInst:HINSTANCE,hPrevinst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
-
- LOCAL wc:WNDCLASSEX
- LOCAL msg:MSG
-
- invoke GetSystemMetrics,SM_CYSCREEN
- mov maxy,eax ; recuperer les dimensions de l'écran
- invoke GetSystemMetrics,SM_CXSCREEN
- mov maxx,eax ; pour fixer les limites
- shr eax,1
- mov ecx,diam
- shr ecx,1
- sub eax,ecx
- mov posx,eax ; et pour positionner la balle au milieu et en bas
- mov eax,maxy
- sub eax,diam
- mov posy,eax
- mov wc.cbSize,SIZEOF WNDCLASSEX
- mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS ; double clic OK
- mov wc.lpfnWndProc,OFFSET WndProc
- mov wc.cbClsExtra,NULL
- mov wc.cbWndExtra,NULL
- push hInstance
- pop wc.hInstance
- invoke CreateSolidBrush,000000FFh ; couleur balle = couleur de fond
- mov wc.hbrBackground,eax
- mov wc.lpszMenuName,NULL
- mov wc.lpszClassName,OFFSET ClassName
- invoke LoadIcon,hInstance,ID_icon
- mov hicon,eax
- mov wc.hIcon,eax
- mov wc.hIconSm,eax
- invoke LoadCursor,NULL,IDC_ARROW
- mov wc.hCursor,eax
- invoke RegisterClassEx,addr wc ; fenetre avec styles adaptées :
- invoke CreateWindowEx,WS_EX_TOPMOST+WS_EX_TOOLWINDOW,\; tjrs au dessus
- ADDR ClassName,ADDR AppName,\ ; pas de barre d'icône
- WS_POPUP,\ ; pas de barre de titre
- posx,posy,\
- maxx,maxy,\
- NULL,NULL,hInstance,NULL
- mov hwnd,eax
-
- boucle_message :
-
- invoke GetMessage,ADDR msg,NULL,0,0
- cmp eax,0
- je fin_boucle_message
- invoke TranslateMessage,ADDR msg
- invoke DispatchMessage,ADDR msg
- jmp boucle_message
-
- fin_boucle_message:
-
- mov eax,msg.wParam
- ret
-
- WinMain ENDP
-
- WndProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
-
- LOCAL pt:POINT
- LOCAL rect:RECT
-
- .IF uMsg == WM_CREATE ; creation ?
- invoke LoadMenu,hInstance,IDR_MENU ; on load le menu
- invoke GetSubMenu,eax,NULL ; qu'on passe en submenu
- mov hmenu,eax
- invoke CreateEllipticRgn,0,0,diam,diam ; creation d'une rgn ronde
- invoke SetWindowRgn,hWnd,eax,1 ; pour y associer la fenetre
- invoke ShowWindow,hWnd,SW_SHOWNORMAL ; et la rendre visible
- invoke UpdateWindow,hWnd
- mov n.cbSize,SIZEOF NOTIFYICONDATA ; pour être "joignable"...
- push hWnd
- pop n.hwnd
- mov n.uID,0
- mov n.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
- mov n.uCallbackMessage,ICONMSG ; ( le message de retour )
- mov eax,hicon
- mov n.hIcon,eax
- invoke lstrcpy,ADDR n.szTip,ADDR AppName
- invoke Shell_NotifyIcon,NIM_ADD,ADDR n ; création d'un tray icon
-
- .ELSEIF uMsg == WM_DESTROY ; c'est fini ?
- invoke DestroyMenu,hmenu ; menu...
- invoke Shell_NotifyIcon,NIM_DELETE,ADDR n ; tray icon...
- invoke PostQuitMessage,NULL
-
- .ELSEIF uMsg == WM_KEYDOWN && wParam == VK_ESCAPE ; touche Escape ?
- invoke DestroyWindow,hwnd
- ; clic droit ou dblclic gauche ?
- .ELSEIF uMsg == WM_RBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK
- invoke GetCursorPos,ADDR pt ; recuperer la pos du curseur
- invoke SetForegroundWindow,hwnd ; et afficher le menu
- invoke TrackPopupMenu,hmenu,TPM_HORIZONTAL,pt.x,pt.y,NULL,hwnd,NULL
- ; clic gauche et thread off ?
- .ELSEIF uMsg == WM_LBUTTONDOWN && dragflag == 0 && threadflag == 0
- mov dragflag,1 ; drag commence
- invoke GetCursorPos,ADDR pt
- mov eax,pt.x
- mov ecx,pt.y ; recuperer la position de la souris
- mov sourx1,eax
- mov sourx2,eax
- mov soury1,ecx ; initialiser l'historique
- mov soury2,ecx ; des deux dernières positions souris
- mov posx,eax
- mov posy,ecx ; initialiser la position de la balle
- mov xdiff,eax
- mov ydiff,ecx
- invoke GetWindowRect,hwnd,ADDR rect
- mov eax,rect.left ; recuperer la position de la fenetre
- mov ecx,rect.top
- sub xdiff,eax
- sub ydiff,ecx ; calculer le decalage souris-fenetre
- invoke SetCapture,hwnd ; garder le lien avec la souris
- invoke SetTimer,hwnd,1,50,NULL ; pour suivre les mvts de souris
- ; clic gauche et thread on ?
- .ELSEIF uMsg == WM_LBUTTONDOWN && dragflag == 0 && threadflag == 1
- mov stopflag,1 ; demander au thread de s'arreter
- invoke PostMessage,hwnd,WM_LBUTTONDOWN,wParam,lParam ; drag
- ; drag on et relachement clic gauche ?
- .ELSEIF uMsg == WM_LBUTTONUP && dragflag == 1
- mov dragflag,0
- invoke KillTimer,hwnd,1 ; plus besoin de suivre la souris
- mov eax,sourx2
- sub eax,sourx1
- mov ecx,soury2
- sub ecx,soury1 ; deux dernières positions de souris
- mov vectxinit,eax ; pour les vecteurs de deplacements
- mov vectyinit,ecx
- invoke ReleaseCapture ; on peut libèrer la souris
- .IF threadflag == 0 ; pas déjà un thread en cours ?
- mov stopflag,0
- mov eax,OFFSET MonThread
- invoke CreateThread,NULL,NULL,eax,NULL,NULL,ADDR IDthread
- mov hthread,eax
- mov threadflag,1 ; alors on le creer
- .ENDIF
- ; drag on et mvt de souris ?
- .ELSEIF uMsg == WM_MOUSEMOVE && dragflag == 1
- invoke GetCursorPos,ADDR pt
- mov eax,pt.x
- mov ecx,pt.y ; recuperer la position de la souris
- sub eax,xdiff
- sub ecx,ydiff ; decalage avec la fenetre
- mov posx,eax ; mettre à jour position de la balle
- mov posy,ecx ; et deplacer la fenetre
- invoke SetWindowPos,hwnd,HWND_TOPMOST,eax,ecx,NULL,NULL,SWP_NOSIZE
-
- .ELSEIF uMsg == WM_TIMER ; timer ?
- invoke GetCursorPos,ADDR pt
- mov eax,pt.x
- mov ecx,pt.y ; recuperer la position de la souris
- push sourx2
- pop sourx1 ; la dernière devient l'avant dernière
- push soury2
- pop soury1
- mov sourx2,eax ; et l'actuelle devient la dernière
- mov soury2,ecx
-
- .ELSEIF uMsg == WM_COMMAND ; commande du menu ?
- mov eax,wParam
- .IF ax == IDM_quitter ; quitter : on sort
- invoke DestroyWindow,hwnd
- .ELSEIF ax == IDM_parametre ; paramètres : boite de dialogue
- invoke DialogBoxParam,hInstance,DlgParam,hwnd,ADDR ParamDlgProc,NULL
- .ELSEIF ax == IDM_apropos ; a propos : boite de dialogue
- invoke DialogBoxParam,hInstance,DlgInfo,hwnd,ADDR InfoDlgProc,NULL
- .ELSEIF ax == IDM_stopper && threadflag == 1
- mov stopflag,1 ; on demande au thread de s'arreter
- .ENDIF
-
- .ELSEIF uMsg == THREADMSG ; message "j'ai fini" du thread ?
- invoke WaitForSingleObject,hthread,INFINITE
- invoke CloseHandle,hthread
- mov threadflag,0 ; on l'attend avant de continuer
-
- .ELSEIF uMsg == ICONMSG ; message tray icon + clic souris ?
- .IF lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN
- invoke GetCursorPos,ADDR pt ; recuperer la pos de la souris
- invoke SetForegroundWindow,hwnd ; pour afficher le menu
- invoke TrackPopupMenu,hmenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hwnd,NULL
- .ENDIF
-
- .ELSE ; sinon c'est windows qui gère
- invoke DefWindowProc,hWnd,uMsg,wParam,lParam
- ret
-
- .ENDIF
- xor eax,eax
- ret
-
- WndProc ENDP
-
- MonThread PROC
-
- LOCAL tempx:DWORD
- LOCAL tempy:DWORD
- LOCAL bonk:DWORD
-
- mov oldx1,0 ; initialisation de l'historique
- mov oldx2,0 ; des trois dernières positions de la balle
- mov oldx3,0
- mov oldy1,0
- mov oldy2,0
- mov oldy3,0
-
- fild posx ; posx et posy -> convertis en floating point
- fstp fposx
- fild posy
- fstp fposy
-
- fild vectxinit ; idem pour vectxinit et vectyinit
- fmul ajust ; Ajuster pour eviter des vecteurs hors de proportion
- fstp vectx
- fild vectyinit
- fmul ajust
- fstp vecty
-
- .REPEAT
-
- mov bonk,0 ; initialiser le flag pour le son d'impact
- finit
-
- fld fposx
- fadd vectx
- fstp fposx ; posx = posx +vectx
-
- fld fposx
- fistp tempx
- mov eax,maxx
- sub eax,diam
- cmp tempx,eax
- jl @f ; posx > maxx ?
-
- mov tempx,eax
- fild tempx
- fstp fposx ; oui : posx = maxx
- fld vectx
- fchs
- fmul rebond
- fstp vectx ; et vectx = -vectx X rebond
- mov bonk,1
- jmp @suite
-
- @@: mov eax,1
- cmp tempx,eax
- jg @suite ; posx < minix ?
-
- mov tempx,eax
- fild tempx
- fstp fposx ; oui : posx = minix
- fld vectx
- fchs
- fmul rebond
- fstp vectx ; et vectx = -vectx X rebond
- mov bonk,1
-
- @suite:
- fld fposy
- fadd vecty
- fstp fposy ; posy = posy +vecty
-
- fld fposy
- fistp tempy
- mov eax,maxy
- sub eax,diam
- cmp tempy,eax
- jl @f ; posy > maxy ?
-
- mov tempy,eax
- fild tempy
- fstp fposy ; oui : posy = maxy
- fld vecty
- fchs
- fmul rebond
- fstp vecty ; et vecty = -vecty X rebond
- mov bonk,1
- jmp @suite2
-
- @@: mov eax,1
- cmp tempy,eax
- jg @suite2 ; posy < miniy ?
-
- mov tempy,eax
- fild tempy
- fstp fposy ; oui : posy = miniy
- fld vecty
- fchs
- fmul rebond
- fstp vecty ; et vecty = -vecty X rebond
- mov bonk,1
-
- @suite2:
- fld vecty
- fadd gravit
- fstp vecty ; vecty = vecty + gravité
-
- push oldx2 ; mettre à jour l'histo des 3 dernières positions
- pop oldx1
- push oldx3
- pop oldx2
- mov eax,tempx
- mov oldx3,eax ; x1 <- x2 <- x3 <- nouveau x
-
- push oldy2
- pop oldy1
- push oldy3
- pop oldy2
- mov ecx,tempy
- mov oldy3,ecx ; y1 <- y2 <- y3 <- nouveau y
- ; ; plus de mvt ?
- .IF eax==oldx1 && eax==oldx2 && ecx==oldy1 && ecx==oldy2
- mov stopflag,1 ; alors stop
- mov bonk,0
-
- .ELSE
- mov edx,maxy
- sub edx,diam
- .IF ecx==oldy1 && ecx==oldy2 && ecx==edx ; ça roule en bas ?
- fld vectx
- fmul frotte ; vectx = vectx X frotte ( ralentissement )
- fstp vectx
- mov bonk,0
- .ENDIF
-
- .ENDIF
- ; deplacer la balle-fenetre à sa nouvelle position
- invoke SetWindowPos,hwnd,HWND_TOPMOST,tempx,tempy,NULL,NULL,SWP_NOSIZE
-
- .IF bonk==1 && sonflag==1 ; il faut produire un son ?
- invoke PlaySound,ID_bonk,hInstance,SND_RESOURCE or SND_ASYNC
- .ENDIF
-
- invoke Sleep,valpause ; faire un pause bien méritée ;-)
-
- .UNTIL stopflag==1 ; et on recommence jusqu'à ce qu'un STOP soit annoncé
-
- fld fposx
- fistp posx
- fld fposy
- fistp posy ; mettre à jour posx et posy ( les non floating point )
- invoke PostMessage,hwnd,THREADMSG,NULL,NULL ; et prevenir
- ret
-
- MonThread endp
-
- InfoDlgProc PROC hdlg:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
-
- .IF uMsg==WM_INITDIALOG ; c'est l'initialisation ?
- mov eax,maxy
- shr eax,2 ; on positionne la boite en haut à gauche
- invoke SetWindowPos,hdlg,HWND_TOPMOST,eax,eax,NULL,NULL,SWP_NOSIZE
- ; c'est vu ?
- .ELSEIF uMsg==WM_CLOSE || (uMsg==WM_COMMAND && wParam==IDC_BTN1)
- invoke EndDialog,hdlg,NULL ; bye bye...
-
- .ENDIF
- xor eax,eax
- ret
-
- InfoDlgProc ENDP
-
- ParamDlgProc PROC hdlg:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
-
- LOCAL temp:DWORD
- LOCAL errflag:DWORD
-
- .IF uMsg==WM_INITDIALOG
- ; positionner la boite en haut à gauche
- mov eax,maxy
- shr eax,2
- invoke SetWindowPos,hdlg,HWND_TOPMOST,eax,eax,NULL,NULL,SWP_NOSIZE
- ; imposer des limites aux edits
- invoke SendDlgItemMessage,hdlg,IDC_vitesse,EM_SETLIMITTEXT,3,0
- invoke SendDlgItemMessage,hdlg,IDC_rebond,EM_SETLIMITTEXT,3,0
- invoke SendDlgItemMessage,hdlg,IDC_gravit,EM_SETLIMITTEXT,3,0
- invoke SendDlgItemMessage,hdlg,IDC_diam,EM_SETLIMITTEXT,3,0
- ; initialiser les items pour le son
- .IF sonflag == 1
- invoke SendDlgItemMessage,hdlg,IDC_son,BM_SETCHECK,BST_CHECKED,0 ; check on
- invoke SetDlgItemText,hdlg,IDC_textson,ADDR szon ; text "on"
- .ELSE
- invoke SetDlgItemText,hdlg,IDC_textson,ADDR szoff ; text "off"
- .ENDIF
- ; initialiser les items pour la vitesse, le rebond et la gravité
- mov eax,101 ; valpause comprise entre 1 et 101
- sub eax,valpause ; et inversement proportionnelle a
- invoke SetDlgItemInt,hdlg,IDC_vitesse,eax,FALSE ; la vitesse
- fld rebond
- fmul cent ; convertir rebond en pourcent
- fistp temp
- invoke SetDlgItemInt,hdlg,IDC_rebond,temp,FALSE ; et transmettre
- fld gravit
- fmul dix ; gravité entre 0 et 10
- fistp temp ; à convertir en pourcent
- invoke SetDlgItemInt,hdlg,IDC_gravit,temp,FALSE
- invoke SetDlgItemInt,hdlg,IDC_diam,diam,FALSE ; le diametre
- ; annuler ?
- .ELSEIF uMsg==WM_CLOSE || (uMsg==WM_COMMAND && wParam==IDC_annuler)
- invoke EndDialog,hdlg,NULL ; on ferme
-
- .ELSEIF uMsg==WM_COMMAND && wParam==IDC_ok ; clic sur ok ?
- mov errflag,0 ; au depart pas d'erreur
- invoke GetDlgItemInt,hdlg,IDC_vitesse,NULL,FALSE ; la vitesse
- .IF eax>100 ; si depassement de valeur
- invoke ErrMsg,100,ADDR szvitesse ; on affiche msg erreur
- mov errflag,1 ; et on signale l'erreur
- .ELSE
- mov ecx,101 ; sinon on convertit
- sub ecx,eax ; et on met à jour
- mov valpause,ecx
- .ENDIF
- invoke GetDlgItemInt,hdlg,IDC_rebond,NULL,FALSE ; idem rebond
- .IF eax>100
- invoke ErrMsg,100,ADDR szrebond
- mov errflag,1
- .ELSE
- mov temp,eax
- fild temp
- fdiv cent
- fstp rebond
- .ENDIF
- invoke GetDlgItemInt,hdlg,IDC_gravit,NULL,FALSE ; idem gravité
- .IF eax>100
- invoke ErrMsg,100,ADDR szgravit
- mov errflag,1
- .ELSE
- mov temp,eax
- fild temp
- fdiv dix
- fstp gravit
- .ENDIF
- invoke GetDlgItemInt,hdlg,IDC_diam,NULL,FALSE ; le diàmetre...
- .IF eax>maxy || eax <5
- invoke ErrMsg,maxy,ADDR szdiam
- mov errflag,1
- .ELSE
- mov diam,eax ; si pas d'erreur
- invoke CreateEllipticRgn,0,0,diam,diam ; rgn au format
- invoke SetWindowRgn,hwnd,eax,1 ; et on y associe la fenetre
- mov eax,posx
- add eax,diam ; la balle sort de l'écran ?
- .IF eax>maxx ; à droite ?
- mov eax,maxx ; alors on ajuste
- sub eax,diam
- mov posx,eax
- .ENDIF
- mov eax,posy ; idem pour en bas
- add eax,diam
- .IF eax>maxy
- mov eax,maxy
- sub eax,diam
- mov posy,eax
- .ENDIF ; on change le format de la fenetre
- invoke SetWindowPos,hwnd,HWND_TOPMOST,posx,posy,NULL,NULL,SWP_NOSIZE
- .ENDIF
-
- .IF errflag == 0 ; pas d'erreur ?
- invoke EndDialog,hdlg,NULL ; alors on ferme la boite
- .ENDIF ; sinon on reste...
-
- .ELSEIF uMsg==WM_COMMAND && wParam==IDC_son ; check "son" ?
- invoke SendDlgItemMessage,hdlg,IDC_son,BM_GETCHECK,0,0 ; état ?
- .IF eax == BST_CHECKED ; checké ?
- mov sonflag,1 ; oui :texte "on"
- invoke SetDlgItemText,hdlg,IDC_textson,ADDR szon
- .ELSE
- mov sonflag,0 ; non : texte "off"
- invoke SetDlgItemText,hdlg,IDC_textson,ADDR szoff
- .ENDIF
-
- .ENDIF
- xor eax,eax
- ret
-
- ParamDlgProc ENDP
-
- ErrMsg PROC valmax:DWORD,lpmsg:DWORD
-
- LOCAL buffer[64]:BYTE
-
- invoke wsprintf,ADDR buffer,lpmsg,valmax ; on complète le texte
- invoke MessageBox,hwnd,ADDR buffer,ADDR AppName,MB_OK+MB_ICONERROR
- ret ; et on affiche
-
- ErrMsg ENDP
-
- end start
Title BOULINATOR Version MASM32
.486
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\shell32.inc
include \masm32\include\winmm.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\winmm.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
InfoDlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
ParamDlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
ErrMsg PROTO :DWORD,:DWORD
.const
ID_icon equ 20
ID_bonk equ 30
IDR_MENU equ 10000
IDM_stopper equ 10001
IDM_continuer equ 10002
IDM_apropos equ 10003
IDM_quitter equ 10004
IDM_parametre equ 10005
DlgInfo equ 1000
IDC_BTN1 equ 1001
DlgParam equ 2000
IDC_vitesse equ 2001
IDC_rebond equ 2002
IDC_gravit equ 2003
IDC_diam equ 2004
IDC_son equ 2005
IDC_annuler equ 2006
IDC_ok equ 2007
IDC_textson equ 2018
THREADMSG equ WM_USER+1
ICONMSG equ WM_USER+2
.data
ClassName db "Boulinator",0
AppName db "Boulinator",0
szvitesse db "La vitesse doit être comprise entre 0 et %u ",0
szrebond db "Le rebond doit être compris entre 0 et %u ",0
szgravit db "La gravité doit être comprise entre 0 et %u ",0
szdiam db "Le diamètre doit être compris entre 5 et %u ",0
szon db "on",0
szoff db "off",0
dragflag dd 0
threadflag dd 0
stopflag dd 0
sonflag dd 1
valpause dd 10
diam dd 35
fposx REAL8 0.0
fposy REAL8 0.0
vectx REAL8 0.0
vecty REAL8 0.0
rebond REAL8 0.94
frotte REAL8 0.97
gravit REAL8 2.0
ajust REAL8 0.4
cent REAL8 100.0
dix REAL8 10.0
.data?
n NOTIFYICONDATA <>
hInstance HINSTANCE ?
hwnd HWND ?
hicon HWND ?
hmenu HWND ?
hthread HWND ?
maxx dd ?
maxy dd ?
posx dd ?
posy dd ?
IDthread dd ?
sourx1 dd ?
soury1 dd ?
sourx2 dd ?
soury2 dd ?
xdiff dd ?
ydiff dd ?
vectxinit dd ?
vectyinit dd ?
oldx1 dd ?
oldx2 dd ?
oldx3 dd ?
oldy1 dd ?
oldy2 dd ?
oldy3 dd ?
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain PROC hInst:HINSTANCE,hPrevinst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
invoke GetSystemMetrics,SM_CYSCREEN
mov maxy,eax ; recuperer les dimensions de l'écran
invoke GetSystemMetrics,SM_CXSCREEN
mov maxx,eax ; pour fixer les limites
shr eax,1
mov ecx,diam
shr ecx,1
sub eax,ecx
mov posx,eax ; et pour positionner la balle au milieu et en bas
mov eax,maxy
sub eax,diam
mov posy,eax
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS ; double clic OK
mov wc.lpfnWndProc,OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
invoke CreateSolidBrush,000000FFh ; couleur balle = couleur de fond
mov wc.hbrBackground,eax
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,hInstance,ID_icon
mov hicon,eax
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx,addr wc ; fenetre avec styles adaptées :
invoke CreateWindowEx,WS_EX_TOPMOST+WS_EX_TOOLWINDOW,\; tjrs au dessus
ADDR ClassName,ADDR AppName,\ ; pas de barre d'icône
WS_POPUP,\ ; pas de barre de titre
posx,posy,\
maxx,maxy,\
NULL,NULL,hInstance,NULL
mov hwnd,eax
boucle_message :
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax,0
je fin_boucle_message
invoke TranslateMessage,ADDR msg
invoke DispatchMessage,ADDR msg
jmp boucle_message
fin_boucle_message:
mov eax,msg.wParam
ret
WinMain ENDP
WndProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL pt:POINT
LOCAL rect:RECT
.IF uMsg == WM_CREATE ; creation ?
invoke LoadMenu,hInstance,IDR_MENU ; on load le menu
invoke GetSubMenu,eax,NULL ; qu'on passe en submenu
mov hmenu,eax
invoke CreateEllipticRgn,0,0,diam,diam ; creation d'une rgn ronde
invoke SetWindowRgn,hWnd,eax,1 ; pour y associer la fenetre
invoke ShowWindow,hWnd,SW_SHOWNORMAL ; et la rendre visible
invoke UpdateWindow,hWnd
mov n.cbSize,SIZEOF NOTIFYICONDATA ; pour être "joignable"...
push hWnd
pop n.hwnd
mov n.uID,0
mov n.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
mov n.uCallbackMessage,ICONMSG ; ( le message de retour )
mov eax,hicon
mov n.hIcon,eax
invoke lstrcpy,ADDR n.szTip,ADDR AppName
invoke Shell_NotifyIcon,NIM_ADD,ADDR n ; création d'un tray icon
.ELSEIF uMsg == WM_DESTROY ; c'est fini ?
invoke DestroyMenu,hmenu ; menu...
invoke Shell_NotifyIcon,NIM_DELETE,ADDR n ; tray icon...
invoke PostQuitMessage,NULL
.ELSEIF uMsg == WM_KEYDOWN && wParam == VK_ESCAPE ; touche Escape ?
invoke DestroyWindow,hwnd
; clic droit ou dblclic gauche ?
.ELSEIF uMsg == WM_RBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK
invoke GetCursorPos,ADDR pt ; recuperer la pos du curseur
invoke SetForegroundWindow,hwnd ; et afficher le menu
invoke TrackPopupMenu,hmenu,TPM_HORIZONTAL,pt.x,pt.y,NULL,hwnd,NULL
; clic gauche et thread off ?
.ELSEIF uMsg == WM_LBUTTONDOWN && dragflag == 0 && threadflag == 0
mov dragflag,1 ; drag commence
invoke GetCursorPos,ADDR pt
mov eax,pt.x
mov ecx,pt.y ; recuperer la position de la souris
mov sourx1,eax
mov sourx2,eax
mov soury1,ecx ; initialiser l'historique
mov soury2,ecx ; des deux dernières positions souris
mov posx,eax
mov posy,ecx ; initialiser la position de la balle
mov xdiff,eax
mov ydiff,ecx
invoke GetWindowRect,hwnd,ADDR rect
mov eax,rect.left ; recuperer la position de la fenetre
mov ecx,rect.top
sub xdiff,eax
sub ydiff,ecx ; calculer le decalage souris-fenetre
invoke SetCapture,hwnd ; garder le lien avec la souris
invoke SetTimer,hwnd,1,50,NULL ; pour suivre les mvts de souris
; clic gauche et thread on ?
.ELSEIF uMsg == WM_LBUTTONDOWN && dragflag == 0 && threadflag == 1
mov stopflag,1 ; demander au thread de s'arreter
invoke PostMessage,hwnd,WM_LBUTTONDOWN,wParam,lParam ; drag
; drag on et relachement clic gauche ?
.ELSEIF uMsg == WM_LBUTTONUP && dragflag == 1
mov dragflag,0
invoke KillTimer,hwnd,1 ; plus besoin de suivre la souris
mov eax,sourx2
sub eax,sourx1
mov ecx,soury2
sub ecx,soury1 ; deux dernières positions de souris
mov vectxinit,eax ; pour les vecteurs de deplacements
mov vectyinit,ecx
invoke ReleaseCapture ; on peut libèrer la souris
.IF threadflag == 0 ; pas déjà un thread en cours ?
mov stopflag,0
mov eax,OFFSET MonThread
invoke CreateThread,NULL,NULL,eax,NULL,NULL,ADDR IDthread
mov hthread,eax
mov threadflag,1 ; alors on le creer
.ENDIF
; drag on et mvt de souris ?
.ELSEIF uMsg == WM_MOUSEMOVE && dragflag == 1
invoke GetCursorPos,ADDR pt
mov eax,pt.x
mov ecx,pt.y ; recuperer la position de la souris
sub eax,xdiff
sub ecx,ydiff ; decalage avec la fenetre
mov posx,eax ; mettre à jour position de la balle
mov posy,ecx ; et deplacer la fenetre
invoke SetWindowPos,hwnd,HWND_TOPMOST,eax,ecx,NULL,NULL,SWP_NOSIZE
.ELSEIF uMsg == WM_TIMER ; timer ?
invoke GetCursorPos,ADDR pt
mov eax,pt.x
mov ecx,pt.y ; recuperer la position de la souris
push sourx2
pop sourx1 ; la dernière devient l'avant dernière
push soury2
pop soury1
mov sourx2,eax ; et l'actuelle devient la dernière
mov soury2,ecx
.ELSEIF uMsg == WM_COMMAND ; commande du menu ?
mov eax,wParam
.IF ax == IDM_quitter ; quitter : on sort
invoke DestroyWindow,hwnd
.ELSEIF ax == IDM_parametre ; paramètres : boite de dialogue
invoke DialogBoxParam,hInstance,DlgParam,hwnd,ADDR ParamDlgProc,NULL
.ELSEIF ax == IDM_apropos ; a propos : boite de dialogue
invoke DialogBoxParam,hInstance,DlgInfo,hwnd,ADDR InfoDlgProc,NULL
.ELSEIF ax == IDM_stopper && threadflag == 1
mov stopflag,1 ; on demande au thread de s'arreter
.ENDIF
.ELSEIF uMsg == THREADMSG ; message "j'ai fini" du thread ?
invoke WaitForSingleObject,hthread,INFINITE
invoke CloseHandle,hthread
mov threadflag,0 ; on l'attend avant de continuer
.ELSEIF uMsg == ICONMSG ; message tray icon + clic souris ?
.IF lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN
invoke GetCursorPos,ADDR pt ; recuperer la pos de la souris
invoke SetForegroundWindow,hwnd ; pour afficher le menu
invoke TrackPopupMenu,hmenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hwnd,NULL
.ENDIF
.ELSE ; sinon c'est windows qui gère
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc ENDP
MonThread PROC
LOCAL tempx:DWORD
LOCAL tempy:DWORD
LOCAL bonk:DWORD
mov oldx1,0 ; initialisation de l'historique
mov oldx2,0 ; des trois dernières positions de la balle
mov oldx3,0
mov oldy1,0
mov oldy2,0
mov oldy3,0
fild posx ; posx et posy -> convertis en floating point
fstp fposx
fild posy
fstp fposy
fild vectxinit ; idem pour vectxinit et vectyinit
fmul ajust ; Ajuster pour eviter des vecteurs hors de proportion
fstp vectx
fild vectyinit
fmul ajust
fstp vecty
.REPEAT
mov bonk,0 ; initialiser le flag pour le son d'impact
finit
fld fposx
fadd vectx
fstp fposx ; posx = posx +vectx
fld fposx
fistp tempx
mov eax,maxx
sub eax,diam
cmp tempx,eax
jl @f ; posx > maxx ?
mov tempx,eax
fild tempx
fstp fposx ; oui : posx = maxx
fld vectx
fchs
fmul rebond
fstp vectx ; et vectx = -vectx X rebond
mov bonk,1
jmp @suite
@@: mov eax,1
cmp tempx,eax
jg @suite ; posx < minix ?
mov tempx,eax
fild tempx
fstp fposx ; oui : posx = minix
fld vectx
fchs
fmul rebond
fstp vectx ; et vectx = -vectx X rebond
mov bonk,1
@suite:
fld fposy
fadd vecty
fstp fposy ; posy = posy +vecty
fld fposy
fistp tempy
mov eax,maxy
sub eax,diam
cmp tempy,eax
jl @f ; posy > maxy ?
mov tempy,eax
fild tempy
fstp fposy ; oui : posy = maxy
fld vecty
fchs
fmul rebond
fstp vecty ; et vecty = -vecty X rebond
mov bonk,1
jmp @suite2
@@: mov eax,1
cmp tempy,eax
jg @suite2 ; posy < miniy ?
mov tempy,eax
fild tempy
fstp fposy ; oui : posy = miniy
fld vecty
fchs
fmul rebond
fstp vecty ; et vecty = -vecty X rebond
mov bonk,1
@suite2:
fld vecty
fadd gravit
fstp vecty ; vecty = vecty + gravité
push oldx2 ; mettre à jour l'histo des 3 dernières positions
pop oldx1
push oldx3
pop oldx2
mov eax,tempx
mov oldx3,eax ; x1 <- x2 <- x3 <- nouveau x
push oldy2
pop oldy1
push oldy3
pop oldy2
mov ecx,tempy
mov oldy3,ecx ; y1 <- y2 <- y3 <- nouveau y
; ; plus de mvt ?
.IF eax==oldx1 && eax==oldx2 && ecx==oldy1 && ecx==oldy2
mov stopflag,1 ; alors stop
mov bonk,0
.ELSE
mov edx,maxy
sub edx,diam
.IF ecx==oldy1 && ecx==oldy2 && ecx==edx ; ça roule en bas ?
fld vectx
fmul frotte ; vectx = vectx X frotte ( ralentissement )
fstp vectx
mov bonk,0
.ENDIF
.ENDIF
; deplacer la balle-fenetre à sa nouvelle position
invoke SetWindowPos,hwnd,HWND_TOPMOST,tempx,tempy,NULL,NULL,SWP_NOSIZE
.IF bonk==1 && sonflag==1 ; il faut produire un son ?
invoke PlaySound,ID_bonk,hInstance,SND_RESOURCE or SND_ASYNC
.ENDIF
invoke Sleep,valpause ; faire un pause bien méritée ;-)
.UNTIL stopflag==1 ; et on recommence jusqu'à ce qu'un STOP soit annoncé
fld fposx
fistp posx
fld fposy
fistp posy ; mettre à jour posx et posy ( les non floating point )
invoke PostMessage,hwnd,THREADMSG,NULL,NULL ; et prevenir
ret
MonThread endp
InfoDlgProc PROC hdlg:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.IF uMsg==WM_INITDIALOG ; c'est l'initialisation ?
mov eax,maxy
shr eax,2 ; on positionne la boite en haut à gauche
invoke SetWindowPos,hdlg,HWND_TOPMOST,eax,eax,NULL,NULL,SWP_NOSIZE
; c'est vu ?
.ELSEIF uMsg==WM_CLOSE || (uMsg==WM_COMMAND && wParam==IDC_BTN1)
invoke EndDialog,hdlg,NULL ; bye bye...
.ENDIF
xor eax,eax
ret
InfoDlgProc ENDP
ParamDlgProc PROC hdlg:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL temp:DWORD
LOCAL errflag:DWORD
.IF uMsg==WM_INITDIALOG
; positionner la boite en haut à gauche
mov eax,maxy
shr eax,2
invoke SetWindowPos,hdlg,HWND_TOPMOST,eax,eax,NULL,NULL,SWP_NOSIZE
; imposer des limites aux edits
invoke SendDlgItemMessage,hdlg,IDC_vitesse,EM_SETLIMITTEXT,3,0
invoke SendDlgItemMessage,hdlg,IDC_rebond,EM_SETLIMITTEXT,3,0
invoke SendDlgItemMessage,hdlg,IDC_gravit,EM_SETLIMITTEXT,3,0
invoke SendDlgItemMessage,hdlg,IDC_diam,EM_SETLIMITTEXT,3,0
; initialiser les items pour le son
.IF sonflag == 1
invoke SendDlgItemMessage,hdlg,IDC_son,BM_SETCHECK,BST_CHECKED,0 ; check on
invoke SetDlgItemText,hdlg,IDC_textson,ADDR szon ; text "on"
.ELSE
invoke SetDlgItemText,hdlg,IDC_textson,ADDR szoff ; text "off"
.ENDIF
; initialiser les items pour la vitesse, le rebond et la gravité
mov eax,101 ; valpause comprise entre 1 et 101
sub eax,valpause ; et inversement proportionnelle a
invoke SetDlgItemInt,hdlg,IDC_vitesse,eax,FALSE ; la vitesse
fld rebond
fmul cent ; convertir rebond en pourcent
fistp temp
invoke SetDlgItemInt,hdlg,IDC_rebond,temp,FALSE ; et transmettre
fld gravit
fmul dix ; gravité entre 0 et 10
fistp temp ; à convertir en pourcent
invoke SetDlgItemInt,hdlg,IDC_gravit,temp,FALSE
invoke SetDlgItemInt,hdlg,IDC_diam,diam,FALSE ; le diametre
; annuler ?
.ELSEIF uMsg==WM_CLOSE || (uMsg==WM_COMMAND && wParam==IDC_annuler)
invoke EndDialog,hdlg,NULL ; on ferme
.ELSEIF uMsg==WM_COMMAND && wParam==IDC_ok ; clic sur ok ?
mov errflag,0 ; au depart pas d'erreur
invoke GetDlgItemInt,hdlg,IDC_vitesse,NULL,FALSE ; la vitesse
.IF eax>100 ; si depassement de valeur
invoke ErrMsg,100,ADDR szvitesse ; on affiche msg erreur
mov errflag,1 ; et on signale l'erreur
.ELSE
mov ecx,101 ; sinon on convertit
sub ecx,eax ; et on met à jour
mov valpause,ecx
.ENDIF
invoke GetDlgItemInt,hdlg,IDC_rebond,NULL,FALSE ; idem rebond
.IF eax>100
invoke ErrMsg,100,ADDR szrebond
mov errflag,1
.ELSE
mov temp,eax
fild temp
fdiv cent
fstp rebond
.ENDIF
invoke GetDlgItemInt,hdlg,IDC_gravit,NULL,FALSE ; idem gravité
.IF eax>100
invoke ErrMsg,100,ADDR szgravit
mov errflag,1
.ELSE
mov temp,eax
fild temp
fdiv dix
fstp gravit
.ENDIF
invoke GetDlgItemInt,hdlg,IDC_diam,NULL,FALSE ; le diàmetre...
.IF eax>maxy || eax <5
invoke ErrMsg,maxy,ADDR szdiam
mov errflag,1
.ELSE
mov diam,eax ; si pas d'erreur
invoke CreateEllipticRgn,0,0,diam,diam ; rgn au format
invoke SetWindowRgn,hwnd,eax,1 ; et on y associe la fenetre
mov eax,posx
add eax,diam ; la balle sort de l'écran ?
.IF eax>maxx ; à droite ?
mov eax,maxx ; alors on ajuste
sub eax,diam
mov posx,eax
.ENDIF
mov eax,posy ; idem pour en bas
add eax,diam
.IF eax>maxy
mov eax,maxy
sub eax,diam
mov posy,eax
.ENDIF ; on change le format de la fenetre
invoke SetWindowPos,hwnd,HWND_TOPMOST,posx,posy,NULL,NULL,SWP_NOSIZE
.ENDIF
.IF errflag == 0 ; pas d'erreur ?
invoke EndDialog,hdlg,NULL ; alors on ferme la boite
.ENDIF ; sinon on reste...
.ELSEIF uMsg==WM_COMMAND && wParam==IDC_son ; check "son" ?
invoke SendDlgItemMessage,hdlg,IDC_son,BM_GETCHECK,0,0 ; état ?
.IF eax == BST_CHECKED ; checké ?
mov sonflag,1 ; oui :texte "on"
invoke SetDlgItemText,hdlg,IDC_textson,ADDR szon
.ELSE
mov sonflag,0 ; non : texte "off"
invoke SetDlgItemText,hdlg,IDC_textson,ADDR szoff
.ENDIF
.ENDIF
xor eax,eax
ret
ParamDlgProc ENDP
ErrMsg PROC valmax:DWORD,lpmsg:DWORD
LOCAL buffer[64]:BYTE
invoke wsprintf,ADDR buffer,lpmsg,valmax ; on complète le texte
invoke MessageBox,hwnd,ADDR buffer,ADDR AppName,MB_OK+MB_ICONERROR
ret ; et on affiche
ErrMsg ENDP
end start
Conclusion
SACHEZ LE : Si vous déplacer un dossier sur votre bureau ( drag ) en même temps que la balle est en mouvement, la trace de celle-ci reste à l’écran. Le simple passage d’une fenêtre sur cette trace suffit à l’effacer… rien de grave donc, mais c’est un bug quand même ! Je n’ai pas encore trouvé la parade et suis preneur si quelqu’un à des pistes !
Boulinator
Historique
- 12 mars 2006 18:58:49 :
- Je me suis aperçu que la moulinette à "coloriser" avait modifié la mise en page du code source et que la lisibilité était un peu moins bonne qu'à l'origine. ( Quelques passages sont même devenus incorrects : certains ET ("&&") ont été curieusement écorchés ). J'ai donc révisé le format du document pour qu'il rentre proprement dans la fenetre de présentation. Le programme n'a, quant a lui subit , aucune modification...
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
trouver le chemin du bureau ou menu demarrer [ par Cendra ]
voila apres la creation de raccourcis , je cherche a les placer sur le bureau , mais j'ai pas trouver comment localiser le dossier...
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Logiciels
974 Application Server (12.2.4.0)974 APPLICATION SERVER (12.2.4.0)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP mySongBook Player (1.0.0)MYSONGBOOK PLAYER (1.0.0)mySongBook Player est un logiciel gratuit permettant l'accès à une archive de tablatures/partitio... Cliquez pour télécharger mySongBook Player
|