Auswahl mit Maus auf Imagegadget (selektieren)

Für allgemeine Fragen zur Programmierung mit PureBasic.
javabean
Beiträge: 29
Registriert: 16.12.2004 18:47

Auswahl mit Maus auf Imagegadget (selektieren)

Beitrag von javabean »

Hallo!

Ich habe gerade Danilo's Beispiel aus dem PureBoard-Archiv (http://forums.purebasic.com/german/arch ... php?t=4771) ausprobiert, jedoch scheint das Auswahlrechteck auf einem ImageGadget (also Danilo's Beispiel) nicht zu funktionieren :cry: .
Hat da vielleicht jemand eine Idee, wie ich es auch auf einem ImageGadget zum Laufen bringe?


(Ich benutze PureBasic v3.92 auf Windows XP SP1)
schic
Beiträge: 68
Registriert: 25.12.2004 19:04

Beitrag von schic »

um die Konstanten #WM_ etc. zu verwenden, musst Du die
Maloperationen direkt auf´s Fenster ausgeben:

Code: Alles auswählen

;
; by Danilo, 24.11.2003 - german forum
;
;   - modified to a full blown paint program,
;     by Danilo - 09.06.2004, english forum ;)
;
Procedure OnMouseSelection(x,y,width,height)
  Shared Current_ActiveColor
  
  ; Debug "-----"
  ; Debug "Selected:"
  ; Debug "X     : "+Str(x)
  ; Debug "Y     : "+Str(y)
  ; Debug "Width : "+Str(width)
  ; Debug "Height: "+Str(height)
  
  ;UseImage(1)
  If StartDrawing(WindowOutput());ImageOutput())
    Box(x,y,width,height,Current_ActiveColor)
    StopDrawing()
  EndIf
  ;SetGadgetState(1,ImageID()) ; update ImageGadget
EndProcedure


Procedure DrawMouseSelector(hWnd)
  Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX
  Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY
  Shared WindowProc_MouseSelectRect.RECT
  
  If WindowProc_MouseSelectStartX > WindowProc_MouseSelectLastX
    WindowProc_MouseSelectRect\left   = WindowProc_MouseSelectLastX
    WindowProc_MouseSelectRect\right  = WindowProc_MouseSelectStartX
  Else
    WindowProc_MouseSelectRect\left   = WindowProc_MouseSelectStartX
    WindowProc_MouseSelectRect\right  = WindowProc_MouseSelectLastX
  EndIf
  If WindowProc_MouseSelectStartY > WindowProc_MouseSelectLastY
    WindowProc_MouseSelectRect\top    = WindowProc_MouseSelectLastY
    WindowProc_MouseSelectRect\bottom = WindowProc_MouseSelectStartY
  Else
    WindowProc_MouseSelectRect\top    = WindowProc_MouseSelectStartY
    WindowProc_MouseSelectRect\bottom = WindowProc_MouseSelectLastY
  EndIf
  
  hDC = GetDC_(hWnd)
  DrawFocusRect_(hDC,@WindowProc_MouseSelectRect)
  ReleaseDC_(hWnd,hDC)
  ;UpdateWindow_(hWnd) ; Win9x fix?
EndProcedure


Procedure WindowProc(hWnd,Msg,wParam,lParam)
  Shared WindowProc_MouseSelect
  Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX
  Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY
  Shared WindowProc_MouseSelectRect.RECT
  
  Select Msg
    
    Case #WM_LBUTTONDOWN
      MouseX = lParam&$FFFF
      MouseY = (lParam>>16)&$FFFF
      If MouseX =< 600 And MouseY <= 480
        WindowProc_MouseSelect  = 1
        WindowProc_MouseSelectStartX = MouseX
        WindowProc_MouseSelectStartY = MouseY
        ;GetClientRect_(GadgetID(1),winrect.RECT)
        GetClientRect_(hWnd,winrect.RECT)
        MapWindowPoints_(hWnd,0,winrect,2)
        ClipCursor_(winrect)
      EndIf
    Case #WM_LBUTTONUP
      If WindowProc_MouseSelect > 1
        DrawMouseSelector(hWnd)
        If WindowProc_MouseSelectRect\left <> WindowProc_MouseSelectRect\right And WindowProc_MouseSelectRect\top <> WindowProc_MouseSelectRect\bottom
          OnMouseSelection(WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\top,WindowProc_MouseSelectRect\right-WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\bottom-WindowProc_MouseSelectRect\top)
          SetCapture_(0)
        EndIf
      EndIf
      ClipCursor_(0)
      WindowProc_MouseSelect = 0
    Case #WM_MOUSEMOVE
      If WindowProc_MouseSelect > 0 And wParam & #MK_LBUTTON
        If WindowProc_MouseSelect > 1
          DrawMouseSelector(hWnd)
        Else
          WindowProc_MouseSelect + 1
        EndIf
        WindowProc_MouseSelectLastX = lParam&$FFFF
        WindowProc_MouseSelectLastY = (lParam>>16)&$FFFF
        DrawMouseSelector(hWnd)
        SetCapture_(hWnd)
      EndIf
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

OpenWindow(0,0,0,640,500,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Mega Mouse Selector (modified)")
SetWindowCallback(@WindowProc())
CreateGadgetList(WindowID())
ImageGadget(1,0,0,600,480,CreateImage(1,60,48))
 
RandomSeed(666)
 
For a = 0 To 20
  CreateImage(a+2,40,24)
  StartDrawing(ImageOutput())
  col = Random($FFFFFF)
  Box(0,0,40,24,col)
  If a = 0 : Current_ActiveColor = col : EndIf
  StopDrawing()
  ButtonImageGadget(a+2,600,a*24,40,24,ImageID())
Next a
 
CreateImage(25,40,18)
If StartDrawing(ImageOutput())
  Box(1,1,38,16,Current_ActiveColor)
  StopDrawing()
EndIf
TextGadget(24,10,485,100,15,"Active color:")
ImageGadget(25,120,482,40,18,ImageID())

HideWindow(0,0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Gadget
      gadget = EventGadgetID()
      If gadget >= 2 And gadget <= 22
        
        UseImage(gadget) ; get new color
        If StartDrawing(ImageOutput())
          Current_ActiveColor = Point(5,5)
          StopDrawing()
        EndIf
        
        UseImage(25) ; update current color gadget
        If StartDrawing(ImageOutput())
          Box(1,1,38,16,Current_ActiveColor)
          StopDrawing()
        EndIf
        SetGadgetState(25,ImageID())
        
      EndIf
  EndSelect
ForEver
ansonsten schau Dir mal die folgenden Beiträge an:
http://forums.purebasic.com/german/arch ... php?t=1726
http://forums.purebasic.com/german/arch ... php?t=5383
http://forums.purebasic.com/german/arch ... php?t=2914

Mouse_Down auf dem Imagegadget im Callback registrieren, weiss ich allerdings (seit PB 9.2 ?) nicht mehr wie´s geht :(

__________
schic
javabean
Beiträge: 29
Registriert: 16.12.2004 18:47

Beitrag von javabean »

Danke schic!

Ich hab' jetzt herausgefunden, warum Danilo's Beispiel bei PureBasic- Versionen >=v3.92 nicht mehr funktioniert. - Es liegt einfach daran, daß ab v3.92 auch ImageGadgets Events liefern.
Um ein das 'Prä-v3.92-Verhalten' von ImageGadgets wiederherzustellen muß lediglich der #SS_NOTIFY flag aus dem ImageGadget-Style entfernt werden.

Fred hat das im englischen PB-Forum beschrieben:
(http://forums.purebasic.com/english/vie ... hp?t=12830)
...Anyway, you can still remove the #SS_NOTIFY flags from the ImageGadget() style if you want to have the same behaviour than pre 3.92 version....
To solve your problem you can use this:

Code: Alles auswählen

SetWindowLong_(GadgetID(#xxx), #GWL_STYLE, GetWindowLong_(GadgetID(#xxx), #GWL_STYLE) & ~#SS_NOTIFY)
Konkret sieht das mit Danilo's Beispiel dann so aus:

Code: Alles auswählen

;
; by Danilo, 24.11.2003 - german forum
;
;   - modified to a full blown paint program,
;     by Danilo - 09.06.2004, english forum ;)
;
Procedure OnMouseSelection(x,y,width,height)
  Shared Current_ActiveColor

  ;Debug "-----"
  ;Debug "Selected:"
  ;Debug "X     : "+Str(x)
  ;Debug "Y     : "+Str(y)
  ;Debug "Width : "+Str(width)
  ;Debug "Height: "+Str(height)
 
  UseImage(1)
  If StartDrawing(ImageOutput())
    Box(x,y,width,height,Current_ActiveColor)
    StopDrawing()
  EndIf
  SetGadgetState(1,ImageID()) ; update ImageGadget
EndProcedure


Procedure DrawMouseSelector(hWnd)
  Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX
  Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY
  Shared WindowProc_MouseSelectRect.RECT

  If WindowProc_MouseSelectStartX > WindowProc_MouseSelectLastX
    WindowProc_MouseSelectRect\left   = WindowProc_MouseSelectLastX
    WindowProc_MouseSelectRect\right  = WindowProc_MouseSelectStartX
  Else
    WindowProc_MouseSelectRect\left   = WindowProc_MouseSelectStartX
    WindowProc_MouseSelectRect\right  = WindowProc_MouseSelectLastX
  EndIf
  If WindowProc_MouseSelectStartY > WindowProc_MouseSelectLastY
    WindowProc_MouseSelectRect\top    = WindowProc_MouseSelectLastY
    WindowProc_MouseSelectRect\bottom = WindowProc_MouseSelectStartY
  Else
    WindowProc_MouseSelectRect\top    = WindowProc_MouseSelectStartY
    WindowProc_MouseSelectRect\bottom = WindowProc_MouseSelectLastY
  EndIf

  hDC = GetDC_(hWnd)
    DrawFocusRect_(hDC,@WindowProc_MouseSelectRect)
  ReleaseDC_(hWnd,hDC)
  ;UpdateWindow_(hWnd) ; Win9x fix?
EndProcedure


Procedure WindowProc(hWnd,Msg,wParam,lParam)
  Shared WindowProc_MouseSelect
  Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX
  Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY
  Shared WindowProc_MouseSelectRect.RECT

  Select Msg
    Case #WM_LBUTTONDOWN
      MouseX = lParam&$FFFF
      MouseY = (lParam>>16)&$FFFF
      If MouseX =< 600 And MouseY <= 480
        WindowProc_MouseSelect  = 1
        WindowProc_MouseSelectStartX = MouseX
        WindowProc_MouseSelectStartY = MouseY
        GetClientRect_(GadgetID(1),winrect.RECT)
        MapWindowPoints_(hWnd,0,winrect,2)
        ClipCursor_(winrect)
      EndIf
    Case #WM_LBUTTONUP
      If WindowProc_MouseSelect > 1
        DrawMouseSelector(hWnd)
        If WindowProc_MouseSelectRect\left <> WindowProc_MouseSelectRect\right And WindowProc_MouseSelectRect\top <> WindowProc_MouseSelectRect\bottom
          OnMouseSelection(WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\top,WindowProc_MouseSelectRect\right-WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\bottom-WindowProc_MouseSelectRect\top)
          SetCapture_(0)
        EndIf
      EndIf
      ClipCursor_(0)
      WindowProc_MouseSelect = 0
    Case #WM_MOUSEMOVE
      If WindowProc_MouseSelect > 0 And wParam & #MK_LBUTTON
        If WindowProc_MouseSelect > 1
          DrawMouseSelector(hWnd)
        Else
          WindowProc_MouseSelect + 1
        EndIf
        WindowProc_MouseSelectLastX = lParam&$FFFF
        WindowProc_MouseSelectLastY = (lParam>>16)&$FFFF
        DrawMouseSelector(hWnd)
        SetCapture_(hWnd)
      EndIf
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure



OpenWindow(0,0,0,640,500,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Mega Mouse Selector (modified)")
  SetWindowCallback(@WindowProc())
  CreateGadgetList(WindowID())
  ImageGadget(1,0,0,600,480,CreateImage(1,600,480))
  SetWindowLong_(GadgetID(1), #GWL_STYLE, GetWindowLong_(GadgetID(1), #GWL_STYLE) & ~#SS_NOTIFY)
 
  RandomSeed(666)
 
  For a = 0 To 20
    CreateImage(a+2,40,24)
    StartDrawing(ImageOutput())
      col = Random($FFFFFF)
      Box(0,0,40,24,col)
      If a = 0 : Current_ActiveColor = col : EndIf
    StopDrawing()
    ButtonImageGadget(a+2,600,a*24,40,24,ImageID())
  Next a
 
  CreateImage(25,40,18)
  If StartDrawing(ImageOutput())
    Box(1,1,38,16,Current_ActiveColor)
    StopDrawing()
  EndIf
  TextGadget(24,10,485,100,15,"Active color:")
  ImageGadget(25,120,482,40,18,ImageID())
  

HideWindow(0,0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Gadget
      gadget = EventGadgetID()
      If gadget >= 2 And gadget <= 22

        UseImage(gadget) ; get new color
        If StartDrawing(ImageOutput())
          Current_ActiveColor = Point(5,5)
          StopDrawing()
        EndIf

        UseImage(25) ; update current color gadget
        If StartDrawing(ImageOutput())
          Box(1,1,38,16,Current_ActiveColor)
          StopDrawing()
        EndIf
        SetGadgetState(25,ImageID())

      EndIf
  EndSelect
ForEver
schic
Beiträge: 68
Registriert: 25.12.2004 19:04

Beitrag von schic »

auch danke.
Jetzt bin ich, ImageGadget betreffende Events, wieder auf dem
Laufenden ;-) hatte schon länger nichts mehr damit zu tun.

Was mich aber noch interessieren würde, ist, wie man die
Ereignisse MouseXButtonDown, MouseXButtonUp und MouseMove
auf dem ImageGadget erfassen kann.
PB bietet ja nur LeftClick, RightClick, LeftDoubleClick und
RightDoubleClick - wenn ich nichts übersehen habe.

Beim Stöbern in den Foren habe ich dazu nichts gefunden.
________
schic
Silencedoogle
Beiträge: 4
Registriert: 02.04.2009 11:41

Beitrag von Silencedoogle »

PB 4.30

Hallo Zusammen.....

Hab die irgendwie nen leck im Hirn.

Hier Danilos Code

Code: Alles auswählen

 
 
Procedure WindowProc(hWnd,Msg,wParam,lParam)  
  Shared WindowProc_MouseSelect  
  Shared WindowProc_MouseSelectStartX, WindowProc_MouseSelectLastX  
  Shared WindowProc_MouseSelectStartY, WindowProc_MouseSelectLastY  
  Shared WindowProc_MouseSelectRect.RECT  
 
  Select Msg  
    Case #WM_LBUTTONDOWN  
      WindowProc_MouseSelect  = 1  
      WindowProc_MouseSelectStartX = lParam&$FFFF  
      WindowProc_MouseSelectStartY = (lParam>>16)&$FFFF  
      GetClientRect_(hWnd,winrect.RECT)  
      MapWindowPoints_(hWnd,0,winrect,2)  
      ClipCursor_(winrect)  
      ProcedureReturn 0  
    Case #WM_LBUTTONUP  
      If WindowProc_MouseSelect > 1  
        DrawMouseSelector(hWnd)  
        If WindowProc_MouseSelectRect\left <> WindowProc_MouseSelectRect\right And WindowProc_MouseSelectRect\top <> WindowProc_MouseSelectRect\bottom  
          OnMouseSelection(hWnd,WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\top,WindowProc_MouseSelectRect\right-WindowProc_MouseSelectRect\left,WindowProc_MouseSelectRect\bottom-WindowProc_MouseSelectRect\top)  
          SetCapture_(0)  
        EndIf  
      EndIf  
      ClipCursor_(0)  
      WindowProc_MouseSelect = 0  
      ProcedureReturn 0  
    Case #WM_MOUSEMOVE  
      If WindowProc_MouseSelect > 0 And wParam & #MK_LBUTTON  
        If WindowProc_MouseSelect > 1  
          DrawMouseSelector(hWnd)  
        Else  
          WindowProc_MouseSelect + 1  
        EndIf  
        WindowProc_MouseSelectLastX = lParam&$FFFF  
        WindowProc_MouseSelectLastY = (lParam>>16)&$FFFF  
        DrawMouseSelector(hWnd)  
        SetCapture_(hWnd)  
      EndIf  
      ProcedureReturn 0  
  EndSelect  
  old=GetWindowLong_(hWnd,#GWL_USERDATA)  
  If old  
    ProcedureReturn CallWindowProc_(old,hWnd,Msg,wParam,lParam)  
  Else  
    DefWindowProc_(hWnd,Msg,wParam,lParam)  
  EndIf  
EndProcedure  
 
 
 
Procedure SelectorImage(x,y,w,h,hImage)  
  img = ImageGadget(#PB_Any,x,y,w,h,hImage)  
  If img  
    old = SetWindowLong_(GadgetID(img),#GWL_WNDPROC,@WindowProc())  
    SetWindowLong_(GadgetID(img),#GWL_USERDATA,old)  
  EndIf  
  ProcedureReturn img  
EndProcedure  
 
OpenWindow(0,0,0,630,630,"Mega Mouse Selector",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible)  
  If CreateImage(1,300,300)=0  
    MessageRequester("ERROR","Cant create image"):End  
  EndIf  
 
  If StartDrawing(ImageOutput(1))  
    For y = 0 To 299 Step 2  
      For x = 0 To 299 Step 2  
        Plot(x,y,Random($FFFFFF))  
      Next x  
    Next y  
    StopDrawing()  
  EndIf  
 
  CreateGadgetList(WindowID(0))  
  SAGGrap = ScrollAreaGadget(1001, 1, 1, 600, 600, 600, 600, 10, #PB_ScrollArea_Center) 
  gadget1 = SelectorImage( 10, 10,300,300,ImageID(1))  
  gadget2 = SelectorImage(320, 10,300,300,ImageID(1))  
  gadget3 = SelectorImage( 10,320,300,300,ImageID(1))  
  gadget4 = SelectorImage(320,320,300,300,ImageID(1))  
HideWindow(0,0)  
 
Repeat  
  Select WaitWindowEvent()  
    Case #PB_Event_CloseWindow  
      End  
  EndSelect  
ForEver 
; CursorPosition = 143 
; FirstLine = 81 

Ich hab den implementiert.

Funktioniert auch ... aber irgendwie raff ich es nicht anstelle der gezeichneten kästen, nen load image --> GragImage auf das geladene image --> mit Scrollareagadget zu bekommen ....

Ich kann dann im eingefügten Image kein rahmen mehr ziehen.

Im Prinzip will ich mir das Bild anzeigen lassen und dann einen rahmen ziehen um den ausschnitt zu vergrößern.

Is halt nen Zoom.

Hier mein Code.

Code: Alles auswählen

Image = LoadImage(#PB_Any,dat) ; 'dat' is ein beliebiges Bild

ImageGrap = GrabImage(Image, #PB_Any, 1, 1, ImageWidth(Image), ImageHeight(Image))

divbreite=1400-breite
divhoehe=1135-hoehe
    
   If breite < hoehe
      divb=1130/hoehe
      resizefaktor=divb
    Else   
      divb=1421/breite
      resizefaktor=divb
    EndIf

widthsize=breite*resizefaktor
heightsize=hoehe*resizefaktor

ResizeImage(ImageGrap, widthsize, heightsize)

SAGGrap = ScrollAreaGadget(#PB_Any, 1, 1, 1425, 1135, ImageWidth(ImageGrap), ImageHeight(ImageGrap), 10, #PB_ScrollArea_Center)

IAGGrap = ImageGadget(#PB_Any, 0, 0, 0, 0,ImageID(ImageGrap), #PB_Image_Border)

gadget1 = SelectorImage( 1, 1, widthsize, heightsize, GadgetID(IAGGrap))

Procedure SelectorImage(x,y,w,h,hImage)  
  img = ImageGadget(#PB_Any,x,y,w,h,hImage)  
  If img  
    old = SetWindowLong_(GadgetID(img),#GWL_WNDPROC,@WindowProc())  
    SetWindowLong_(GadgetID(img),#GWL_USERDATA,old)  
  EndIf  
  ProcedureReturn img  
EndProcedure

Ist nur ein Auszug, aber vielleicht könnt ihr mir dennoch sagen was Syntaktisch oder Handle mäßig daran schief läuft.

Focus hat nach dem laden des Image ein anderes Window und actives gadget is nen Stringgadget.
Zuletzt geändert von Silencedoogle am 02.04.2009 12:15, insgesamt 1-mal geändert.
Lets Rock and Have fun
Silencedoogle
Beiträge: 4
Registriert: 02.04.2009 11:41

Beitrag von Silencedoogle »

ansich funktionierts schon ....

solange ich das Scrollareagadget und das Imagegadget weglassen und Selectorimage anstelle von IAGGrad ImageGrap übergebe.

aber dann hab ich das prob das ich das geladene Bild nicht ja nicht auf meiner oberfläche zentrieren kan. und wenn nu anstelle von nen A4 nen A2-Bild kommt dann geht ja unter meine buttons welche auf der selben Oberfläche liegen.

Wenn ich im original code von danilo nen SAG vorlegen geht auch ..

ich danke ich übergebe einfach was falsches aber ich steh total aufn schlauch.
Lets Rock and Have fun
Antworten