Page 1 sur 1

Rectangle de sélection

Publié : dim. 03/oct./2004 14:58
par ZapMan
Je cherche la commande API qui permet de tracer un rectangle de selection.

Je parle de ce machin en pointillé clignotants qui permet, dans illustrator, par exemple, de faire une sélection de plusieurs points ou plusieurs objets. On a aussi ça dans les fenêtres du bureau, pour sélectionner plusieurs icônes (on clic à côté d'une icône, on maintient cliqué, on se déplace, et ça fait un rectangle de selection).

Je ne sais même pas comment ça s'appelle en anglais. Si déjà vous savez ça, ça me permettra de faire des recherches...

Publié : dim. 03/oct./2004 15:09
par Oliv
cherche "selection fenetre" dans le musée ça doit y être

Publié : dim. 03/oct./2004 15:10
par Anonyme2
Vois avec Rectangle, FrameRect ou avec la méthode DrawRectangle de l'interface Graphics je crois

Publié : dim. 03/oct./2004 23:46
par ZapMan
Ca semble être "Rubber Band" ou "Focus Rectangle". Je continue à chercher.

http://support.microsoft.com/default.as ... -us;135865

Publié : lun. 04/oct./2004 6:30
par Anonyme2
Oui, j'avais pas bien lu le rectangle clignotant :oops:

Publié : lun. 04/oct./2004 21:31
par ZapMan
Bon, ben c'est DrawFocusRect_.
Cette instruction dessine un rectangle en pointillé en mode XOR

Code : Tout sélectionner

Procedure Set_Rect (x1,y1,x2,y2, *FRect.Rect) 
  If x2<x1 
    mx = x1 
    x1 = x2 
    x2 = mx 
  EndIf 
  If y2<y1 
    my = y1 
    y1 = y2 
    y2 = my 
  EndIf
  If x1<0 : x1 = 0 : EndIf
  If y1<0 : y1 = 0 : EndIf
  *FRect\left = x1 
  *FRect\Top = y1 
  *FRect\Right = x2 
  *FRect\Bottom = y2 
EndProcedure 

If OpenWindow(0,0,0,745,425,#PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_MinimizeGadget,"Démo Rectangle de sélection")
  hdc = GetDC_(WindowID()) 
  DraggingOn = 0
  Repeat
    EventID = WaitWindowEvent()
    If EventID.l = #WM_LBUTTONDOWN 
      GetCursorPos_(@StartPos.Point) ; On mémorise la position de départ du curseur 
      GetWindowRect_(WindowID() ,@SDRect.RECT) 
      If PtInRect_(SDRect,StartPos\x,StartPos\y) ; On vérifie que le curseur est dans la fenêtre 
        StartPos\x - SDRect\Left-2 ; On récupère les coordonnées relatives 
        StartPos\y - SDRect\Top - 27
        MPos.Point\x = StartPos\x
        MPos\y = StartPos\y
        DraggingOn = 1
        Set_Rect(WindowX()+3,WindowY()+29,WindowX()+3+WindowWidth(),WindowY()+29+WindowHeight(),WRect.Rect)
        ClipCursor_(WRect) ; on capture le curseur souris dans notre fenêtre pour être sûr de récupérer le #WM_LBUTTONUP
      EndIf
    EndIf

    If GetAsyncKeyState_(#VK_LBUTTON) And DraggingOn ; Tant que le bouton est maintenu cliqué 
      GetCursorPos_(@OverPos.Point) 
      GetWindowRect_(WindowID() ,@SDRect.RECT) 
      If PtInRect_(SDRect,OverPos\x,OverPos\y) ; On vérifie que le curseur est dans la fenêtre 
        OverPos\x - SDRect\Left-2 ; On récupère les coordonnées relatives 
        OverPos\y - SDRect\Top - 27
        If MPos.Point\x<>StartPos.Point\x Or MPos\y<>StartPos\y  ; Si on s'est déplacé depuis le départ 
          Set_Rect (StartPos\x,StartPos\y,MPos.Point\x,MPos\y, FRect.Rect) 
          DrawFocusRect_(hdc,FRect) ; On efface la version précédente 
        EndIf
        If MPos.Point\x<>OverPos\x Or MPos\y<>OverPos\y
          Set_Rect (StartPos\x,StartPos\y,OverPos\x,OverPos\y, FRect.Rect)
          MPos\x = OverPos\x ; On mémorise les coordonnées du nouveau tracé
          MPos\y = OverPos\y
          DrawFocusRect_(hdc,FRect) ; Et on le traçe
        EndIf
      EndIf 
    EndIf
    
    If EventID.l = #WM_LBUTTONUP And DraggingOn 
      Set_Rect (StartPos\x,StartPos\y,MPos.Point\x,MPos\y, FRect.Rect) 
      DrawFocusRect_(hdc,FRect) ; On efface le dernier tracé
      DraggingOn = 0
      ClipCursor_(0) ; on libère le curseur
    EndIf
  Until  EventID = #PB_Event_CloseWindow

  ReleaseDC_(WindowID(),hdc)
EndIf

Maintenant que la solution est touvée, ce post mériterait d'être classé dans "Trucs et Astuces"

Publié : mar. 05/oct./2004 6:30
par Oliv
Voilà :D

Publié : jeu. 20/juil./2006 8:56
par Progi1984
Passage en V4

Code : Tout sélectionner

Procedure Set_Rect (x1,y1,x2,y2, *FRect.Rect)
  If x2<x1
    mx = x1
    x1 = x2
    x2 = mx
  EndIf
  If y2<y1
    my = y1
    y1 = y2
    y2 = my
  EndIf
  If x1<0 : x1 = 0 : EndIf
  If y1<0 : y1 = 0 : EndIf
  *FRect\left = x1
  *FRect\Top = y1
  *FRect\Right = x2
  *FRect\Bottom = y2
EndProcedure

If OpenWindow(0,0,0,745,425,"Démo Rectangle de sélection",#PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_MinimizeGadget)
  hdc = GetDC_(WindowID(0))
  DraggingOn = 0
  Repeat
    EventID = WaitWindowEvent()
    If EventID.l = #WM_LBUTTONDOWN
      GetCursorPos_(@StartPos.Point) ; On mémorise la position de départ du curseur
      GetWindowRect_(WindowID(0) ,@SDRect.RECT)
      If PtInRect_(SDRect,StartPos\x,StartPos\y) ; On vérifie que le curseur est dans la fenêtre
        StartPos\x - SDRect\Left-2 ; On récupère les coordonnées relatives
        StartPos\y - SDRect\Top - 27
        MPos.Point\x = StartPos\x
        MPos\y = StartPos\y
        DraggingOn = 1
        Set_Rect(WindowX(0)+3,WindowY(0)+29,WindowX(0)+3+WindowWidth(0),WindowY(0)+29+WindowHeight(0),WRect.Rect)
        ClipCursor_(WRect) ; on capture le curseur souris dans notre fenêtre pour être sûr de récupérer le #WM_LBUTTONUP
      EndIf
    EndIf

    If GetAsyncKeyState_(#VK_LBUTTON) And DraggingOn ; Tant que le bouton est maintenu cliqué
      GetCursorPos_(@OverPos.Point)
      GetWindowRect_(WindowID(0) ,@SDRect.RECT)
      If PtInRect_(SDRect,OverPos\x,OverPos\y) ; On vérifie que le curseur est dans la fenêtre
        OverPos\x - SDRect\Left-2 ; On récupère les coordonnées relatives
        OverPos\y - SDRect\Top - 27
        If MPos.Point\x<>StartPos.Point\x Or MPos\y<>StartPos\y  ; Si on s'est déplacé depuis le départ
          Set_Rect (StartPos\x,StartPos\y,MPos.Point\x,MPos\y, FRect.Rect)
          DrawFocusRect_(hdc,FRect) ; On efface la version précédente
        EndIf
        If MPos.Point\x<>OverPos\x Or MPos\y<>OverPos\y
          Set_Rect (StartPos\x,StartPos\y,OverPos\x,OverPos\y, FRect.Rect)
          MPos\x = OverPos\x ; On mémorise les coordonnées du nouveau tracé
          MPos\y = OverPos\y
          DrawFocusRect_(hdc,FRect) ; Et on le traçe
        EndIf
      EndIf
    EndIf
   
    If EventID.l = #WM_LBUTTONUP And DraggingOn
      Set_Rect (StartPos\x,StartPos\y,MPos.Point\x,MPos\y, FRect.Rect)
      DrawFocusRect_(hdc,FRect) ; On efface le dernier tracé
      DraggingOn = 0
      ClipCursor_(0) ; on libère le curseur
    EndIf
  Until  EventID = #PB_Event_CloseWindow

  ReleaseDC_(WindowID(0),hdc)
EndIf

Publié : jeu. 20/juil./2006 12:01
par gnozal
Autre possibilité (de mes archives, auteur = ?, modifié par moi [PB3.94])

Code : Tout sélectionner

Procedure SelectionRectangle(WindowNumber.l, Color.l, *SelectionRECT.RECT)
  Protected DC.l, BKG.l, w.l, H.l, R.RECT, Rim.l, HiTitle.l, X.l, Y.l, lplb.LOGBRUSH
  Protected CPos.POINT, EV.l, DMX.l, DMY.l, X1.l, Y1.l, xOld.l, yOld.l, Pen.l
  If IsWindow(WindowNumber)
    UseWindow(WindowNumber)
    DC = GetDC_(WindowID(WindowNumber))
    BKG = CreateCompatibleDC_(DC)
    w = WindowWidth() : H = WindowHeight()
    ;
    GetWindowRect_(WindowID(WindowNumber), @R)
    ClipCursor_(@R)
    Rim = (R\right - R\left - w) / 2
    HiTitle = R\bottom - R\top - H - Rim
    ;
    SelectObject_(BKG,CreateImage(0,w,H))
    BitBlt_(BKG,0,0,w,H,DC,0,0,#SRCCOPY)
    X = WindowMouseX() : Y = WindowMouseY()
    lplb\lbStyle = #BS_SOLID
    lplb\lbColor = Color
    ;
    Repeat
      EV = WindowEvent()
      GetCursorPos_(@CPos)
      DMX = CPos\X : DMY=CPos\Y
      ;
      X1 = WindowMouseX() : Y1 = WindowMouseY()
      If X1 = -1 : X1 = DMX - WindowX() + Rim : EndIf
      If Y1 = -1 : Y1 = DMY - WindowY() + Rim - HiTitle : EndIf
      If X1 <> xOld Or Y1 <> yOld
        If X <> X1 Or Y <> Y1
          BitBlt_(DC,0,0,w,H,BKG,0,0,#SRCCOPY)
          SelectObject_(DC,GetStockObject_(#NULL_BRUSH ))
          ;Pen=ExtCreatePen_(#PS_COSMETIC| #PS_ALTERNATE,1,@lplb,0,0)
          Pen=ExtCreatePen_(#PS_COSMETIC| #PS_DOT,1,@lplb,0,0)
          SetBkMode_(DC, #TRANSPARENT)
          ;SetBkColor_(DC, #Black)
          SelectObject_(DC,Pen)
          Rectangle_(DC,X,Y,X1,Y1)
          xOld = X1 : yOld = Y1
          DeleteObject_(Pen)
        EndIf
      Else
        Delay(20)
      EndIf
    Until GetAsyncKeyState_(#VK_LBUTTON) = 0
    ;
    ClipCursor_(0)
    BitBlt_(DC,0,0,w,H,BKG,0,0,#SRCCOPY)
    DeleteDC_(BKG)
    ReleaseDC_(WindowID(WindowNumber), DC)
    If IsImage(0)
      FreeImage(0)
    EndIf
    ;
    *SelectionRECT.RECT\left = X : *SelectionRECT\top = Y
    *SelectionRECT\right = X1 : *SelectionRECT\bottom = Y1
  EndIf 
EndProcedure
Retourne le rectangle dans *SelectionRECT

Publié : jeu. 20/juil./2006 16:24
par einander

Code : Tout sélectionner

;RubberBox PB 4 
;einander 20 jul 2006 
;http://www.purebasic.fr/english/viewtopic.php?T=12674&highlight=rubberbox
Global _Drawing,_MX,_MY,_MK,_DX,_DY

Macro MOU ;-MOU
   _MX=WindowMouseX(0) 
   _MY=WindowMouseY(0)     
   _MK=Abs(GetAsyncKeyState_(#VK_LBUTTON) +GetAsyncKeyState_(#VK_RBUTTON)*2+GetAsyncKeyState_(#VK_MBUTTON)*3)/$8000   
   _DX=DesktopMouseX()
   _DY=DesktopMouseY()
   If GetAsyncKeyState_(#VK_ESCAPE):End:EndIf  ; esto sobra aqui, pero podria ser util<<<<<<<<<<<<<
EndMacro

Procedure RubberBox(RGB,*Rubber.RECT)    
   BKG = CreateCompatibleDC_(_Drawing) 
   Wi=WindowWidth(EventWindow()):He=WindowHeight(EventWindow()) 
   GetWindowRect_(WindowID(EventWindow()), @R.RECT)   ; Window bounding rectangle 
   Rim = (R\right - R\left - Wi) / 2              ; window rim width 
   HiTitle = R\bottom - R\top - He - Rim     ;title height 
   SelectObject_(BKG,CreateImage(0,Wi,He))  ; keep background image  
   BitBlt_(BKG,0,0,Wi,He,_Drawing,0,0,#SRCCOPY) 
   x=_MX:y=_MY 
   lb.LOGBRUSH\lbStyle=#BS_SOLID 
   lb\lbColor=RGB 
   Repeat 
      EV=WindowEvent() 
      X1=WindowMouseX(0):Y1=WindowMouseY(0) 
      If X1=-1 : X1=_DX-WindowX(0)-Rim : EndIf 
      If Y1=-1 : Y1=_DY-WindowY(0)-HiTitle : EndIf 
      If X1<>xOld Or Y1 <>yOld 
         If x<>X1 Or y <>Y1 
            BitBlt_(_Drawing,0,0,Wi,He,BKG,0,0,#SRCCOPY) ;delete previous rectangle 
            SelectObject_(_Drawing,GetStockObject_(#NULL_BRUSH )) 
            Pen=ExtCreatePen_(#PS_COSMETIC| #PS_ALTERNATE,1,@lb,0,0)              
            SelectObject_(_Drawing,Pen) 
            Rectangle_(_Drawing,x,y,X1,Y1)    
            xOld=X1:yOld=Y1 
            DeleteObject_(Pen)                  
         EndIf 
      Else 
         Delay(20) 
      EndIf 
   Until  GetAsyncKeyState_(#VK_LBUTTON)=0    
   BitBlt_(_Drawing,0,0,Wi,He,BKG,0,0,#SRCCOPY)  ; restore background 
   DeleteDC_(BKG) ;recover memory 
   *Rubber.RECT\left=x:*Rubber\top=y:*Rubber\right=X1:*Rubber\bottom=Y1 ; keep coords of selected rectangle 
FreeImage(0)
EndProcedure 
    ;_____________________________________________________ 
    
hwnd = OpenWindow(0, 100, 100, 600,400,"RubberBox", #WS_OVERLAPPEDWINDOW ) 
_Drawing=StartDrawing(WindowOutput(0))
    
Repeat 
   EV = WaitWindowEvent()    
   MOU
   If EV=#WM_LBUTTONDOWN 
      RubberBox(#Red,@Rubber.RECT) ;Rubber.Rect is updated with the selected values 
      Box(Rubber\left,Rubber\top,Rubber\right-Rubber\left,Rubber\bottom-Rubber\top,Random($FFFFFF))
   EndIf 
Until EV= #PB_Event_CloseWindow