Announcement

Collapse
No announcement yet.

GDI+ and Scrolling

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • GDI+ and Scrolling

    GDI+, as with the PB graphic commands allows me to draw outside a drawing area, IE a Graphic control.
    How do I scroll to uncover the portion that is not displayed?

    The attached code demonstrates what I mean. (Mostly derived from José Roca's most excellent Forum)
    Here I draw vertical lines that start off inside the drawing area, but quickly exceed it's area
    and most are drawn outside of the viewing area.

    I had though that GdipTranslateWorldTransform would allow me to reposition the view origin and
    a simple graphic refresh would give me what I want (as in clicking the 'Scroll button' in the top right), but of course it's not that simple. Nothing is with Windows.

    Am I aproaching this in the wrong way? Do I have to handle it the same way as if using the
    ordinary drawing API - IE something like ScrollwindowEX and then draw the uncovered portion?
    I was hoping that GDI+ handled all this stuff.

    Code:
    #PBForms Created V1.51
    '------------------------------------------------------------------------------
    ' The first line in this file is a PB/Forms metastatement.
    ' It should ALWAYS be the first line of the file. Other   
    ' PB/Forms metastatements are placed at the beginning and 
    ' end of "Named Blocks" of code that should be edited     
    ' with PBForms only. Do not manually edit or delete these 
    ' metastatements or PB/Forms will not be able to reread   
    ' the file correctly.  See the PB/Forms documentation for 
    ' more information.                                       
    ' Named blocks begin like this:    #PBFORMS BEGIN ...     
    ' Named blocks end like this:      #PBFORMS END ...       
    ' Other PB/Forms metastatements such as:                  
    '     #PBFORMS DECLARATIONS                               
    ' are used by PB/Forms to insert additional code.         
    ' Feel free to make changes anywhere else in the file.    
    '------------------------------------------------------------------------------
    
    #Compile Exe
    
    '------------------------------------------------------------------------------
    '   ** Includes **
    '------------------------------------------------------------------------------
    #PBForms Begin Includes 
    %USEMACROS = 1
    #If Not %Def(%WINAPI)
        #Include "WIN32API.INC"
    #EndIf
    #If Not %Def(%COMMCTRL_INC)
        #Include "COMMCTRL.INC"
    #EndIf
    #Include "PBForms.INC"
    #PBForms End Includes
    #Include "GDIPLUS.INC"
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Constants **
    '------------------------------------------------------------------------------
    #PBForms Begin Constants 
    %IDD_DIALOG1  =  101
    %IDC_GRAPHIC1 = 1001
    %IDC_Scroll   = 1002
    #PBForms End Constants
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Declarations **
    '------------------------------------------------------------------------------
    Declare CallBack Function ShowDIALOG1Proc()
    Declare Function ShowDIALOG1(ByVal hParent As Dword) As Long
    #PBForms Declarations
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Main Application Entry Point **
    '------------------------------------------------------------------------------
    Function PBMain()
        PBFormsInitComCtls (%ICC_WIN95_CLASSES Or %ICC_DATE_CLASSES Or _
            %ICC_INTERNET_CLASSES)
       Local hr As Long
       Local hDlg As Dword
       Local token As Dword
       Local StartupInput As GdiplusStartupInput
    
       ' Initialize GDI+
       StartupInput.GdiplusVersion = 1
       hr = GdiplusStartup(token, StartupInput, ByVal %Null)
       If hr =-1 Then
          MsgBox "Error initializing GDI+"
          Exit Function
       End If
        ShowDIALOG1 %HWND_DESKTOP   
    End Function
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** CallBacks **
    '------------------------------------------------------------------------------
    CallBack Function ShowDIALOG1Proc()
       Local hDC As Dword
       Local n As Single
       Local hStatus As Long
       Static pGraphics As Dword
       Local pPen As Dword 
    
    
        Select Case As Long CbMsg
            Case %WM_INITDIALOG
               Graphic Get DC To hDC 
               hStatus = GdipCreateFromHDC(hdc, pGraphics)
               hStatus = GdipSetPageUnit(pGraphics, %Unitinch) ' // Set the page units to inches
               hStatus = GdipCreatePen1(GdiPlusMakeARGBColor(255, 0, 0, 0), 2, %UnitPixel, pPen) ' // Create a Pen    
               For n=1 To 150
                   GdipDrawLine pGraphics, pPen, n/10 , 0, n/10 , n/10 ' // Draw the line 
               Next n 
              ' Graphic ReDraw
              ' // Cleanup 
               If pPen Then GdipDeletePen(pPen)  
    '           If pGraphics Then GdipDeleteGraphics(pGraphics)  'This should be done on exit
    
            Case %WM_NCACTIVATE
                Static hWndSaveFocus As Dword
                If IsFalse CbWParam Then
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ElseIf hWndSaveFocus Then
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                End If
    
            Case %WM_COMMAND
                ' Process control notifications
                Select Case As Long CbCtl 
                'I expected **something** like this to work.
                'Here's the question - how do I scoll to the part that is not displayed????
                    Case %IDC_Scroll
                        If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then   
                            'Graphic Get DC To hDC 
                            'hStatus = GdipCreateFromHDC(hdc, pGraphics) 
                            'hStatus = GdipSetPageUnit(pGraphics, %Unitinch)    
                            hStatus = GdipTranslateWorldTransform(pGraphics, 1, 0, %MatrixOrderPrepend) 
                            Graphic ReDraw
                        End If
    
                End Select
        End Select
    End Function
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Dialogs **
    '------------------------------------------------------------------------------
    Function ShowDIALOG1(ByVal hParent As Dword) As Long
        Local lRslt As Long
    
    #PBForms Begin Dialog %IDD_DIALOG1->->
        Local hDlg  As Dword
    
        Dialog New hParent, "GDI+ Scrolling - It's a Mystery to me!", 70, 70, _
            356, 248, %WS_POPUP Or %WS_BORDER Or %WS_DLGFRAME Or %WS_SYSMENU Or _
            %WS_CLIPSIBLINGS Or %WS_VISIBLE Or %DS_MODALFRAME Or %DS_3DLOOK Or _
            %DS_NOFAILCREATE Or %DS_SETFONT, %WS_EX_CONTROLPARENT Or %WS_EX_LEFT _
            Or %WS_EX_LTRREADING Or %WS_EX_RIGHTSCROLLBAR, To hDlg
        Control Add Graphic, hDlg, %IDC_GRAPHIC1, "", 50, 25, 295, 195, %WS_CHILD _
            Or %WS_VISIBLE Or %WS_BORDER
        Graphic Attach hDlg, %IDC_GRAPHIC1
        Graphic Color %Black, %White
        Graphic Clear
        Control Add Button,  hDlg, %IDC_Scroll, "Scroll", 5, 25, 40, 30
    #PBForms End Dialog
    
        Dialog Show Modal hDlg, Call ShowDIALOG1Proc To lRslt
    
    #PBForms Begin CleanUp %IDD_DIALOG1
    #PBForms End CleanUp
    
        Function = lRslt
    End Function
    '------------------------------------------------------------------------------

  • #2
    Never Mind.
    I've decided to work around the scrolling issue.

    Ian.

    Comment


    • #3
      Originally posted by Ian Vincent View Post
      Never Mind.
      nice to know that GDIPlus does that to other people too!

      If user interaction is required then that is not (as I understand it) part of what GDIplus does. But if you have a bitmap built using GDIplus presumably you can move your viewport around it?

      Comment


      • #4
        Chris,
        Yes, it's all a bit confusing and I thought it did make scrolling easy.
        Turns out (I think) that isn't the case.
        The biggest problem I am having is finding **useful** documentation on each of the functions.
        José Roca's forum is easily the best, but even there, he assumes a more than basic level of knowledge of GDI+.
        Another issue is that there doesn't seem to be an 'official' PB endorsed GDIPLUS.INC. Some I've located don't seem to be incomplete, some mess up the use of PB's WIN32API.INC
        It would be nice if PB generated an official one.

        As for the scrolling issue, yes you are correct. It looks like I have to draw into a DC off screen and then move a viewport around. Right now that is more effort than I want to put in.

        I'm sticking with GDI+ for other functions like gradient fill and antialiasing though.

        Ian

        Comment


        • #5
          Originally posted by Ian Vincent View Post
          It would be nice if PB generated an official one.
          Can't see it - PB does not appear to use GDIPlus. I use it for photographic images which don't look so good using the built-in functions.
          Originally posted by Ian Vincent View Post
          It looks like I have to draw into a DC off screen and then move a viewport around. Right now that is more effort than I want to put in.
          I wonder how hard can be. Maybe someone hereabouts has done it?

          Comment


          • #6
            In all truth, it probably isn't that hard.
            I just need to concentrate on getting a display on screen.
            Once I have what I need, maybe I will come back to the scrolling bit. As with a lot of things, once you start to use something regularly, you come to understand it better. I just hope that happens to me with GDI+ (and soon!).

            Comment


            • #7
              Wouldn't GRAPHIC STRETCH do what you want?
              Use GRAPHIC BITMAP NEW to create a bitmap in memory to hold the full image.
              Use GRAPHIC WINDOW NEW to create the window to display the visible part of that image.
              Then use GRAPHIC STRETCH to copy the part of the bitmap you want to display into the window.

              Paul.

              Comment


              • #8
                Thanks Paul.
                That might do, I'm not sure until I play with it.
                Part of my problem is going to be calculating the size of the memory bitmap before I start drawing. What I am doing is displaying seismic data, which can have an arbitary number of traces of an arbirary length. Couple this with an arbitary number of traces/inch (or cm if you prefer), I need to do a bit of thinking.
                On top of that, I will want to be able to use the mouse position to identify a trace.

                It's all stuff I have done before using the built in PB graphics routines, but they are for my purposes slow and I run into the aliasing problem.
                For a bit of an idea of what I am ultimately looking at improving on:

                http://www.seismatters.com/408%20Viewer.html

                this is a sample output of my existing software. It doesn't have scrolling or antialiasing or gratient fill capability, which I am aiming for.

                Anyway, I'm travelling for the next couple of days, so won't have access to the forums.

                Thanks to all who have replied.

                Ian.

                Comment


                • #9
                  Ian,
                  to play with, try this:
                  Code:
                  'PBCC5.0 program
                  #BREAK ON
                  #CONSOLE OFF
                  FUNCTION PBMAIN () AS LONG
                  
                  LOCAL hBMP,hWin  AS DWORD
                  
                  
                  ImageFile$="c:\storms5.bmp"  'the image to use. Make it bigger than the window for the scrolling to work.
                  
                  'get the size of the image
                  nFile& = FREEFILE
                  OPEN ImageFile$ FOR BINARY AS nFile&
                  GET #nFile&, 19, nWidth&
                  GET #nFile&, 23, nHeight&
                  CLOSE nFile&
                  
                  'create a bitmap and load the image
                  GRAPHIC BITMAP LOAD  ImageFile$,nWidth&,nHeight& TO hBMP
                  
                  xSize!=400:ySize!=400
                  xOffset!=0:yOffset!=0
                  
                  'create a window to display the part image in the screen
                  GRAPHIC WINDOW "Test image scrolling",0,0,ySize!,xSize! TO hWin
                  
                  'make the window the target of any subsequent graphic operations
                  GRAPHIC ATTACH hWin, 0
                  
                  StepSize!=10
                  
                  QuitFlag&=0
                  DO
                      GRAPHIC INKEY$ TO k$
                      
                      SELECT CASE LEN(k$)
                          CASE 0
                              SLEEP 1
                              
                          CASE 1
                              IF k$ = $ESC  OR k$="q" OR k$="Q" THEN
                                  quitflag&=1
                              END IF
                              
                          CASE 2
                              SELECT CASE ASC(RIGHT$(k$,1))
                                  CASE 72 'up arrow
                                      yOffset!=yOffset!-StepSize!
                                      IF yOffset! <0 THEN
                                          yOffset!=0
                                      END IF
                                      
                                      
                                  CASE 80 'down arrow
                                      yOffset!=yOffset!+StepSize!
                                      IF yOffset! >(nHeight&-ySize!) THEN
                                          yOffset!=nHeight&-ySize!
                                      END IF
                  
                                      
                                  CASE 77 'right arrow
                                      xOffset!=xOffset!+StepSize!
                                      IF xOffset! >(nWidth&-xSize!) THEN
                                          xOffset!=nWidth&-xSize!
                                      END IF
                  
                                      
                                  CASE 75 'left arrow
                                      xOffset!=xOffset!-StepSize!
                                      IF xOffset! <0 THEN
                                          xOffset!=0
                                      END IF
                                      
                              END SELECT
                              
                          END SELECT
                          
                      GRAPHIC STRETCH hBMP,0,(xOffset!,yOffset!) - (xOffset!+xSize!,yOffset!+ySize!) TO (0,0) - (xSize!,ySize!)
                                          
                  LOOP UNTIL QuitFlag&
                  
                  END FUNCTION
                  Paul. (Former Seismic Observer)

                  Comment


                  • #10
                    Thanks Paul.
                    Nice to see a fellow ex-Observer here.
                    Who were you with?

                    To keep it on topic though, I will try your example in a couple of days - have to shut down now. I see what you are getting at though.

                    Ian.

                    Comment


                    • #11
                      Ian,
                      I was originally with the Norwegian company Geco which merged with a German company Prakla and was taken over by Schlumberger. It was 15 years ago so there may have been a few more name changes since!

                      The code I posted was quickly thrown together just to show how you might do it. It will need more work.

                      For identifying traces you can add GRAPHIC WINDOW CLICK to get the location of a mouse click and then take off the scroll offset to find the location of the trace in the original plot. That's maybe not so straight forward when the traces ovelap.

                      Paul.

                      Comment

                      Working...
                      X