Umriss-Box optisch hervorheben?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
garfield9992003
Beiträge: 35
Registriert: 24.04.2005 03:49

Umriss-Box optisch hervorheben?

Beitrag von garfield9992003 »

Hallo zusammen.

Kaum ist mein 1. Problem gelöst, ist schon das 2. Problem da :(

Ich habe eine Form, in der im Moment eine grau-gefüllte Box ist. Später soll diese durch ein Bild (Bildmap) ersetzt werden.
In dieser Box ist eine zweite Box (Umriss), diese soll dazu dienen einen Bereich innerhalb des späteren Bildes zu markieren.
Bei mir kann ich die Position und die Grösse dieser Box per Maus steuern, habe allerdings im Beispiel-Code darauf verzichtet.

Mein Problem:

Nun sollte diese Box sich optisch hervorheben, wie z.B. schwarz/weiss blinken (fade) oder animiert mit schwarz-weissen Linien.
Man kann es mit der Scanoberfläche eines Twain-Treibers, oder mit dem Maskierungswerkzeug eines Bildbearbeitungsprogramm vergleichen.

Zudem wäre es ein nettes Feature, den nicht markierten Bereich des Bildes etwas abgedunkelt darzustellen. Ich habe einen Code zum dunklermachen des ganzen Bildes. Den werde ich wohl umgeschrieben bekommen, so dass das eigentlich funktionieren müsste.

Wer weiss, wie ich es anstellen kann, den "Maskierungsrahmen" optisch hervorzuheben?

Grüße

Frank

Code: Alles auswählen

x1.l=50 
x2.l=200 
y1.l=50 
y2.l=200 
If OpenWindow(0,100,150,600,270,#PB_Window_SystemMenu,"Test") 
  CreateGadgetList(WindowID()) 
  hWnd=ImageGadget(1,10,10,250,250,LoadImage(0,"")) 
  CreateImage(0,250,250) 
  StartDrawing(ImageOutput()) 
  Box(0,0,250,250,RGB(160,160,160)) 
  FrontColor(0, 0, 0) 
  DrawingMode(1 | 4) 
  Box(x1, y1, x2-x1, y2-y1) 
  StopDrawing()    
  SetGadgetState(1,UseImage(0)) 
EndIf
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Du könntest beispielsweise den Markierungsrahmen so machen, daß er auf seiner Linie einfach das Bild invertiert. Somit ist er immer sichtbar (außer bei 128,128,128 grau :)). Eine andere Möglichkeit wäre, daß Du den Rahmen nicht 1 Pixel breit, sondern 3 Pixel breit machst, wobei dann die jeweils äußeren Linien schwarz sind und die innere weiß. Somit müßte er auch auf jeden Fall gesehen werden, ist alledings 3 Pixel breit statt einem.
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Umriss-Box optisch hervorheben?

Beitrag von Danilo »

garfield9992003 hat geschrieben:Nun sollte diese Box sich optisch hervorheben, wie z.B. schwarz/weiss blinken (fade) oder animiert mit schwarz-weissen Linien.
Hier mal ein altes Beispiel von mir, Window Selector.pb:

Code: Alles auswählen

; 
; by Danilo, 24.11.2003 - german forum 
; 
Procedure OnMouseSelection(x,y,width,height) 
  Debug "-----" 
  Debug "Selected:" 
  Debug "X     : "+Str(x) 
  Debug "Y     : "+Str(y) 
  Debug "Width : "+Str(width) 
  Debug "Height: "+Str(height) 
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 
      WindowProc_MouseSelect  = 1 
      WindowProc_MouseSelectStartX = lParam&$FFFF 
      WindowProc_MouseSelectStartY = (lParam>>16)&$FFFF 
      GetClientRect_(hWnd,winrect.RECT) 
      MapWindowPoints_(hWnd,0,winrect,2) 
      ClipCursor_(winrect)
    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,400,400,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Mega Mouse Selector") 
  SetWindowCallback(@WindowProc()) 
HideWindow(0,0) 

Repeat 
  Select WaitWindowEvent() 
    Case #PB_Event_CloseWindow 
      End 
  EndSelect 
ForEver

Und hier das ganze schnell an ImageGadgets angepasst
und bissl verändert:

Code: Alles auswählen

; 
; modified by Danilo, 27.04.2005 - german forum
;
;   original version: Window Selector.pb
;   (by Danilo, 24.11.2003 - german forum)
;
Global gadget1, gadget2, gadget3, gadget4


Procedure OnMouseSelection(hWnd,x,y,width,height)
  Select hWnd
    Case GadgetID(gadget1) : Gadget$ = "gadget 1"
    Case GadgetID(gadget2) : Gadget$ = "gadget 2"
    Case GadgetID(gadget3) : Gadget$ = "gadget 3"
    Case GadgetID(gadget4) : Gadget$ = "gadget 4"
    Default: Gadget$ = "unbekannt"
  EndSelect

  Debug "-----" 
  Debug "Selected:"
  Debug "hWnd  : "+Gadget$
  Debug "X     : "+Str(x) 
  Debug "Y     : "+Str(y) 
  Debug "Width : "+Str(width) 
  Debug "Height: "+Str(height) 
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)
    InvertRect_(hDC,@WindowProc_MouseSelectRect)
    ;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 
      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,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Mega Mouse Selector")
  If CreateImage(1,300,300)=0
    MessageRequester("ERROR","Cant create image"):End
  EndIf

  If StartDrawing(ImageOutput())
    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())
  gadget1 = SelectorImage( 10, 10,300,300,ImageID())
  gadget2 = SelectorImage(320, 10,300,300,ImageID())
  gadget3 = SelectorImage( 10,320,300,300,ImageID())
  gadget4 = SelectorImage(320,320,300,300,ImageID())
HideWindow(0,0) 

Repeat 
  Select WaitWindowEvent() 
    Case #PB_Event_CloseWindow 
      End 
  EndSelect 
ForEver
In der Prozedur 'DrawMouseSelector' brauchst Du nur die
letzten 4 Zeilen anpassen. Dort kannst Du dann auch einen
Rahmen schwarz/weiß hinmalen - halt was Du willst.

Vielleicht hilft es ja als kleiner Anfang...
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
garfield9992003
Beiträge: 35
Registriert: 24.04.2005 03:49

Beitrag von garfield9992003 »

Hallo, danke für deine Antwort.

Ein breiter Rahmen kommt leider nicht in Frage, da die MArkierung dann zu ungenau wird :(

Mit invertieren müsste man sehen, ob es wirklich optisch auffällt. Ich gebe mich mal dran, den Rahmen zu plotten anstatt zu "boxen".

Den nicht markierten BEreich abdunkeln ist erledigt, das funktioniert nun.

Grüße

Frank
garfield9992003
Beiträge: 35
Registriert: 24.04.2005 03:49

Beitrag von garfield9992003 »

@Danilo - Danke für das sehr gute Beispiel - nur in diesem Fall muss das Markierungsfenster immer sichtbar und jeder der 4 Begrenzungen einzeln verschiebbar sein - Aber das Klasse-Teil von dir kann ich bestimmt später einsetzen.

Mein Prob ist lediglich die optische Kennzeichnung des Rahmens :(

Ich habe nun in meinem obigen Code den 2. Box-Befehl durch das folgende ersetzt:

Code: Alles auswählen

  ;Box(x1, y1, x2-x1, y2-y1)
  farbe=RGB(0,0,0)
  s=5
  For x=x1 To x2:Plot(x,y1,farbe): farbe=RGB(Red(farbe)+s,Green(farbe)+s,Blue(farbe)+s): Next
  For y=y1 To y2:Plot(x2,y,farbe): farbe=RGB(Red(farbe)+s,Green(farbe)+s,Blue(farbe)+s): Next
  For x=x2 To x1 Step -1:Plot(x,y2,farbe): farbe=RGB(Red(farbe)+s,Green(farbe)+s,Blue(farbe)+s): Next
  For y=y2 To y1 Step -1:Plot(x1,y,farbe): farbe=RGB(Red(farbe)+s,Green(farbe)+s,Blue(farbe)+s): Next
Wenn man das Ding dann animieren könnte, dann wäre es ja schon geschafft :) Nur ich habe keinen Schimmer von Paletten-Animation oder so. Oder ist meine Idee blöd?

Grüße

Frank
Rothammel
Beiträge: 53
Registriert: 17.09.2006 17:22

Hy mal für PB 4.00

Beitrag von Rothammel »

Hy
wollte das auch mal testen, und dachte werde es mal aktualiesiern

Code: Alles auswählen

;
; modified by Danilo, 27.04.2005 - german forum
;
;   original version: Window Selector.pb
;   (by Danilo, 24.11.2003 - german forum)
;
Global gadget1, gadget2, gadget3, gadget4


Procedure OnMouseSelection(hWnd,x,y,width,height)
  Select hWnd
    Case GadgetID(gadget1) : Gadget$ = "gadget 1"
    Case GadgetID(gadget2) : Gadget$ = "gadget 2"
    Case GadgetID(gadget3) : Gadget$ = "gadget 3"
    Case GadgetID(gadget4) : Gadget$ = "gadget 4"
    Default: Gadget$ = "unbekannt"
  EndSelect

  Debug "-----"
  Debug "Selected:"
  Debug "hWnd  : "+Gadget$
  Debug "X     : "+Str(x)
  Debug "Y     : "+Str(y)
  Debug "Width : "+Str(width)
  Debug "Height: "+Str(height)
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)
    InvertRect_(hDC,@WindowProc_MouseSelectRect)
    ;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
      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))
  gadget1 = SelectorImage( 10, 10,300,300,0)
  gadget2 = SelectorImage(320, 10,300,300,0)
  gadget3 = SelectorImage( 10,320,300,300,0)
  gadget4 = SelectorImage(320,320,300,300,0)
HideWindow(0,0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
  EndSelect
ForEver
PB 4.00 Code
Antworten