Procedure FullView (cFile ) function DC_GetWorkArea()

This forum is for eXpress++ general support.
Message
Author
User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Procedure FullView (cFile ) function DC_GetWorkArea()

#1 Post by Eugene Lutsenko »

Hey, Roger!

Your DC_GetWorkArea () function correctly determines the available desktop area based on the taskbar location. I tried to redo the procedure FullView (cFile ) function DC_GetWorkArea(). But it does not display the window in the top position, but in the center of the height, and part of it is obtained on the taskbar. Could you tell me how to change this procedure so that it displays the file in the desktop area.

And more.

To make the file visible, you must move the window to update it. Is it possible to make a refresh directly in this function and not outside it?

It would be good if after displaying the file there was no exit from the procedure before closing the window by the user. This is so that you do not have to stop its execution after the display .

Full debug program below:

Code: Select all

     PROCEDURE AppSys
     // Рабочий стол остается окном приложения
     RETURN
     
     ********************************************************************************
     FUNCTION Main()
     
     DC_IconDefault(1000)

     SET DECIMALS TO 15
     SET DATE GERMAN
     SET ESCAPE On

     // Размеры изображения по X и по Y
*    nXSize = 4096
*    nYSize = 3072

     nXSize = 1920
     nYSize = 1080

     oScr := DC_WaitOn('Немного подождите! Идет формирование и масштабирование изображения!')

     // Create new bitmap with given size
     oPS := XBPPRESSPACE() :new() :Create()
     oBMP := XBPBITMAP() :New() :Create()
*    oBMP:Make( nXSize, nYSize, nPlanes, nBits )
     oBMP:Make( nXSize, nYSize )
     oBMP:presSpace( oPS )
     
     // here your GRA* Code 
     
     **** Закрасить фон прямоугольника ***************
*    GraSetColor( oPS, GRA_CLR_WHITE, GRA_CLR_WHITE )
     GraSetColor( oPS, BD_LIGHTGREY, BD_LIGHTGREY )
     GraBox( oPS, { 0, 0 }, { nXSize, nYSize }, GRA_FILL ) 

     *######################################################################################################################
     ArchimSpiral()                     // Графическая функция     <<<===###################################################
     *######################################################################################################################

     *My image original, my image scaled
     
     ERASE("MyImageOriginal.JPG")
     oBMP:saveFile("MyImageOriginal.JPG",XBPBMP_FORMAT_JPG)
     
*    aNewSize := {1366,768}             // Новый размер изображения
     ********* Роджер ***********************
     aWorkArea := DC_GetWorkArea()
     nWidth    := aWorkArea[3] - aWorkArea[1]
     nHeight   := aWorkArea[4] - aWorkArea[2]
     aNewSize := {nWidth,nHeight}       // Новый размер изображения
     ****************************************
     oRet = BMP2BMP(oBMP,aNewSize)      // Масштабирование изображения
     ERASE("MyImageScaled.JPG")
     oRet:saveFile("MyImageScaled.JPG",XBPBMP_FORMAT_JPG) 

     DC_Impl(oScr)                                                   

*    FullView( "MyImageOriginal.JPG" )
     FullView( "MyImageScaled.JPG" )
     WAIT

*    LB_Warning('Готово!')

CLOSE ALL
RETURN NIL

******************************************************************************************************************
FUNCTION ArchimSpiral()

LOCAL GetList[0], GetOptions, oSay, oDevice
LOCAL aX[100000], aY[100000], aZ[100000]                                         // Координаты X,Y,Z точек облака

ERASE('_ColumnNames.arx');ERASE('_482.txt')    // Стереть файлы: _ColumnNames.arx и _482.txt

AFILL(aX,0)
AFILL(aY,0)
AFILL(aZ,0)

***** Задать атрибуты линии

aAttr := Array( GRA_AL_COUNT )                             // Массив для атрибутов линии  
aAttr [ GRA_AL_TYPE  ] := GRA_LINETYPE_DEFAULT
graSetAttrLine( oPS, aAttr )                  

PointsCount = 1000                         // число точек
TurnovCount =   20                         // число виктов спирали

u = 360 / PointsCount * TurnovCount        // угол между точками


**** Поиск минимальных и максимальных X и Y и нормирование

mMinX = +99999999999
mMaxX = -99999999999
mMinY = +99999999999
mMaxY = -99999999999

i = 0

GradRad := 3.14159265358979323846 / 180    // Коэффициент перевода аргументов тригонометрических функций из градусов в радианы

FOR p=1 TO PointsCount

    mX := i * COS( p*u * GradRad )
    mY := i * SIN( p*u * GradRad )

    i++

    mMinX = MIN(mMinX, mX)
    mMaxX = MAX(mMaxX, mX)
    mMinY = MIN(mMinY, mY)
    mMaxY = MAX(mMaxY, mY)

NEXT

***** Расчет позиций для одного по X поля изображения шириной nXSizeAr
***** и двух равных промежутков между ними d и слева и справа от изображений до края окна

X_Max := nXSize
Y_Max := nYSize                                     // Размер графического окна для самого графика в пикселях

IF .NOT. FILE('_XYSize.txt')
*  LB_Warning(L('Необходимо запустить режим генерации облака точек!','4.8. Геокогнитивная подсистема "Эйдос"' )
   StrFile(STR(nXSize,9)+' '+STR(nYSize,9), '_XYSize.txt')          // Запись текстового файла с параметрами nXSize, nYSize
ELSE
*  StrFile(STR(nXSize,9)+' '+STR(nYSize,9), '_XYSize.txt')          // Запись текстового файла с параметрами nXSize, nYSize
   nXSize = VAL(SUBSTR(FileStr('_XYSize.txt'), 1,9))                // Загрузка параметра nXSize из текстового файла
   nYSize = VAL(SUBSTR(FileStr('_XYSize.txt'),11,9))                // Загрузка параметра nYSize из текстового файла
ENDIF

dX = (X_Max-0.8*Y_Max)/2
dY = (Y_Max-0.8*Y_Max)/2

i = 0

FOR p=1 TO PointsCount

    mX := i * COS( p*u * GradRad )
    mY := i * SIN( p*u * GradRad )

    mZ := p

    i++

    aX[i] =         0.8 * Y_Max * ( mX - mMinX) / (mMaxX - mMinX) + dX
    aY[i] = Y_Max - 0.8 * Y_Max * ( mY - mMinY) / (mMaxY - mMinY) - dY
    aZ[i] =                         mZ

    aAttr [ GRA_AL_COLOR ] := GRA_CLR_RED                  // Задать цвет    линии
    aAttr [ GRA_AL_WIDTH ] := 1                            // Задать толщину линии
    graSetAttrLine( oPS, aAttr )                  
    GraArc ( oPS, { aX[i], aY[i] }, 2 )                    // Рисует круг стилем линии

    aAttr [ GRA_AL_COLOR ] := GRA_CLR_DARKGRAY             // Задать цвет    линии
    aAttr [ GRA_AL_WIDTH ] := 1                            // Задать толщину линии
    graSetAttrLine( oPS, aAttr )                  
    GraArc ( oPS, { aX[i], aY[i] }, 3 )                    // Рисует круг стилем линии

NEXT

PointsCount = i

***** Создать БД для координат X,Y,Z точек облака

aStructure := { { "Num"   , "N",  15, 0 }, ;
                { "pX"    , "N",  15, 7 }, ;
                { "pY"    , "N",  15, 7 }, ;
                { "pZ"    , "N",  15, 7 }, ;
                { "pRed"  , "N",   3, 0 }, ; 
                { "pGreen", "N",   3, 0 }, ; 
                { "pBlue" , "N",   3, 0 }  }
DbCreate( 'Points_XYZ', aStructure )

CLose All

USE Points_XYZ EXCLUSIVE NEW
SELECT Points_XYZ

FOR p=1 TO PointsCount
    
    APPEND BLANK
    REPLACE Num WITH p
    REPLACE pX  WITH aX[p]
    REPLACE pY  WITH aY[p]
    REPLACE pZ  WITH aZ[p]

NEXT

  CLose All

RETURN nil

*******************************************************************
******** Масштбалирование bmp-изображения от Джимми
*******************************************************************
FUNCTION BMP2BMP( oBMP, aXbpSize )

LOCAL oHuge
LOCAL oTiny
LOCAL oPS
LOCAL oRet
LOCAL nBits
LOCAL nPlanes

  IF aXbpSize[ 2 ] > 0
      oHuge    := oBMP
      nBits    := oBMP:bits
      nPlanes  := oBMP:planes

      oPS := XBPPRESSPACE() :new():Create()
      oTiny := XBPBITMAP() :New() :Create()
      if nBits > 1 .or. nPlanes > 1
         oTiny:Make( aXbpSize[ 1 ], aXbpSize[ 2 ], nPlanes, nBits )
      ELSE
         oTiny:Make( aXbpSize[ 1 ], aXbpSize[ 2 ] )
      ENDIF
      oTiny:presSpace( oPS )

      oHuge:Draw( oPS, { 0, 0, aXbpSize[1], aXbpSize[2] },,,GRA_BLT_BBO_IGNORE  )
      oRet := oTiny
   ELSE
      oRet := oBMP
   ENDIF

RETURN oRet

**************************************************************
/*
 * This procedure displays an image file in a separate window (xdemo.exe)
 */
**************************************************************
PROCEDURE FullView( cFile )

   LOCAL oDlg, oImage, oPS, aSize, aPos

  /*
   * Only bitmap and meta files are supported
   */
   IF cFile <> NIL            .AND. ;
     ( ".BMP" $ Upper( cFile ) .OR. ;
       ".EMF" $ Upper( cFile ) .OR. ;
       ".GIF" $ Upper( cFile ) .OR. ;
       ".JPG" $ Upper( cFile ) .OR. ;
       ".PNG" $ Upper( cFile ) .OR. ;
       ".MET" $ Upper( cFile )      )

     /*
      * Create hidden dialog window
      */
      oDlg := XbpDialog():new( AppDesktop(),,,{100,100} )
      oDlg:taskList := .F.
      oDlg:visible  := .F.
      oDlg:title    := cFile
      oDlg:close    := {|mp1,mp2,obj| obj:destroy() }
      oDlg:create()


     /*
      * Create a presentation space and connect it with the device
      * context of :drawingArea
      */
      oPS := XbpPresSpace():new():create( oDlg:drawingArea:winDevice() )

      IF ".BMP" $ Upper( cFile ) .OR. ;
         ".GIF" $ Upper( cFile ) .OR. ;
         ".JPG" $ Upper( cFile ) .OR. ;
         ".PNG" $ Upper( cFile )

        /*
         * File contains a bitmap. Limit the window size to a range
         * between 16x16 pixel and the screen resolution
         */
         oImage   := XbpBitmap():new():create( oPS )
         oImage:loadFile( cFile )

         aSize    := { oImage:xSize, oImage:ySize }

*        aSize[1] := Max( 16, Min( aSize[1], AppDeskTop():currentSize()[1] ) )    // ###############
*        aSize[2] := Max( 16, Min( aSize[2], AppDeskTop():currentSize()[2] ) )
*        aSize    := oDlg:calcFrameRect( {0,0, aSize[1], aSize[2]} )   // <<<===#######################

*        oDlg:setSize( {aSize[3], aSize[4]} )

     ********* Роджер ***********************
     aWorkArea := DC_GetWorkArea()
     nWidth    := aWorkArea[3] - aWorkArea[1]
     nHeight   := aWorkArea[4] - aWorkArea[2]
     aNewSize := {nWidth,nHeight}       // Новый размер изображения
     aSize    := oDlg:calcFrameRect( {0,0, aSize[1], aSize[2]} )   // <<<===#######################
     oDlg:setSize( {nWidth, nHeight} )   // <<<===#######################
     ****************************************

         /*
          * The window must react to xbeP_Paint to redraw the bitmap
          */
         oDlg:drawingarea:paint := {|x,y,obj| x:=obj:currentSize(), ;
                                     oImage:draw( oPS, {0, 0, x[1], x[2]}, ;
                                     {0, 0, oImage:xSize, oImage:ySize},,;
                                     GRA_BLT_BBO_IGNORE), Sleep(0.1) }
      ELSE
        /*
         * Display a meta file. It has no size definition for the image
         */
         oImage := XbpMetafile():new():create()
         oImage:load( cFile )
         aSize := { 600, 400 }
         oDlg:setSize( aSize )
         oDlg:drawingarea:paint := {|| oImage:draw( oPS, XBPMETA_DRAW_SCALE ), Sleep(0.1) }

      ENDIF

     /*
      * Display the window centered on the desktop
      */
      aPos:= CenterPos( oDlg:currentSize(), AppDesktop():currentSize() )   // <<<===#######################
      oDlg:setPos( aPos )
      oDlg:show()
      SetAppFocus( oDlg )
   ENDIF

* Refresh, Pause    // <<<===#######################   

RETURN

******** Display a warning message
******** Может выдавать сообщения элементами массива и без ctitle:

*message := {}
*AADD(message,'1-е сообщение')
*AADD(message,'2-е сообщение')
*AADD(message,'3-е сообщение')
*LB_Warning( message )

FUNCTION LB_Warning( message, ctitle )

  LOCAL aMsg := {}
  DEFAULT cTitle TO ''
  IF valtype(message) # 'A'
    aadd(aMsg,message)
  ELSE
    aMsg := message
  ENDIF
  IF LEN(ALLTRIM(cTitle)) > 0
     DC_MsgBox( ,,aMsg,cTitle)
  ELSE
     DC_MsgBox( ,,aMsg,'(C) Система "Эйдос"')
  ENDIF

RETURN NIL
[/size]

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#2 Post by Auge_Ohr »

FullView() use XbpDialog() so you need a Eventloop for GUI (NOT WAIT :naughty: )

i guess Express++ have a better Way to show a Image Full Screen ...
greetings by OHR
Jimmy

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#3 Post by Eugene Lutsenko »

Auge_Ohr wrote:FullView() use XbpDialog() so you need a Eventloop for GUI (NOT WAIT :naughty: )

i guess Express++ have a better Way to show a Image Full Screen ...
I, too, guess, for example saw ImgView.prg. But I can not based on it to do what I need. All I need is what's in ImgView.prg is obtained by clicking on the button: "Full View". This should display a file with a predefined name by its size. No items should be in the file image window anymore. Other features that have ImgView.prg, I don't need it now either (for this task).

As if from this function to remove all unnecessary for this task?

User avatar
rdonnay
Site Admin
Posts: 4813
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#4 Post by rdonnay »

Use the below function: AlignWindow( oDlg )

Code: Select all

FUNCTION AlignWindow( oDlg )

LOCAL aCoords := DC_GetWorkArea(), nBottom, nLeft

nBottom := AppDeskTop():currentSize()[2] - aCoords[4]
nLeft := AppDeskTop():currentSize()[1]/2 - oDlg:currentSize()[1]/2

oDlg:setPos({nLeft,nBottom})

RETURN nil
The eXpress train is coming - and it has more cars.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#5 Post by Eugene Lutsenko »

Many thanks to everyone!!! Everything turned out great! I inserted a debug function in the system to form a large image in memory and display it on the screen after scaling, then everything worked as planned!

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#6 Post by Eugene Lutsenko »

Roger!

I've modified the function FullView() a bit so that it can display an image either at the top of the window without a taskbar, or as usual in the center of the screen.

Code: Select all

***********************************************************************
/*
 * This procedure displays an image file in a separate window
 */
***********************************************************************
PROCEDURE FullView( cFile, mPar )

   LOCAL oDlg, oImage, oPS, aSize, aPos
   LOCAL lBGClr := XBPSYSCLR_TRANSPARENT

  /*
   * Only bitmap and meta files are supported
   */
   IF cFile <> NIL            .AND. ;
     ( ".BMP" $ Upper( cFile ) .OR. ;
       ".EMF" $ Upper( cFile ) .OR. ;
       ".GIF" $ Upper( cFile ) .OR. ;
       ".JPG" $ Upper( cFile ) .OR. ;       
       ".PNG" $ Upper( cFile ) .OR. ;
       ".MET" $ Upper( cFile )      )

     /*
      * Create hidden dialog window
      */
      oDlg := XbpDialog():new( AppDesktop(),,,{100,100} )
      oDlg:taskList   := .F.
      oDlg:visible    := .F.
      oDlg:title      := cFile
      oDlg:sizeRedraw := .T.
      oDlg:close      := {|mp1,mp2,obj| obj:destroy() }
      oDlg:create()

     /*
      * Create a presentation space and connect it with the device
      * context of :drawingArea
      */
      oPS := XbpPresSpace():new():create( oDlg:drawingArea:winDevice() )

      IF ".BMP" $ Upper( cFile ) .OR. ;
         ".GIF" $ Upper( cFile ) .OR. ;
         ".JPG" $ Upper( cFile ) .OR. ;       
         ".PNG" $ Upper( cFile )

        /*
         * File contains a bitmap. Limit the window size to a range
         * between 16x16 pixel and the screen resolution
         */
         oImage   := XbpBitmap():new():create( oPS )
         oImage:loadFile( cFile )

         IF oImage:transparentClr <> GRA_CLR_INVALID
            lBGClr := XBPSYSCLR_DIALOGBACKGROUND
         ENDIF

         *************** ЗДЕСЬ ВЗЯТЬ ОПРЕДЕЛЕННЫЕ ВЫШЕ РАЗМЕРЫ ИЗОБРАЖЕНИЯ <<<===##########################

         aSize    := { oImage:xSize, oImage:ySize }

         aSize[1] := Max( 16, Min( aSize[1], AppDeskTop():currentSize()[1] ) )
         aSize[2] := Max( 16, Min( aSize[2], AppDeskTop():currentSize()[2] ) )
         aSize    := oDlg:calcFrameRect( {0,0, aSize[1], aSize[2]} )

         oDlg:setSize( {aSize[3], aSize[4]} )

         /*
          * The window must react to xbeP_Paint to redraw the bitmap
          */
         oDlg:drawingarea:paint := {|x,y,obj| x:=obj:currentSize(), ;
                                     oImage:draw( oPS, {0, 0, x[1], x[2]}, ;
                                     {0, 0, oImage:xSize, oImage:ySize},,;
                                     GRA_BLT_BBO_IGNORE), Sleep(0.1) }
      ELSE
        /*
         * Display a meta file. It has no size definition for the image
         */
         oImage := XbpMetafile():new():create()
         oImage:load( cFile )
         aSize := { 600, 400 }
         oDlg:setSize( aSize )
         oDlg:drawingarea:paint := {|x,y,obj| x:=obj:currentSize(), ;
                                              oImage:draw( oPS, {0, 0, x[1], x[2]}),;
                                              Sleep(0.1) }
         lBGClr := XBPSYSCLR_DIALOGBACKGROUND
      ENDIF

     /*
      * Set the background color for the dialog's drawingarea.
      * Per default, the transparent color is used to avoid 
      * flicker during refreshs. For transparent images and 
      * metafiles, however, color gray is set instead, see above. 
      * This is done to prevent bits of the desktop from being
      * visible in transparent areas of the bitmap/metafile image.
      * Alternatively, transparency could be explicitly switched
      * off for bitmapped images.
      */
      oDlg:drawingArea:SetColorBG( lBGClr )

     /*
      * Display the window centered on the desktop
      */
      DO CASE
         CASE mPar = "по верху"
              AlignWindow( oDlg )
         CASE mPar = "по центру"
              aPos:= CenterPos( oDlg:currentSize(), AppDesktop():currentSize() )
              oDlg:setPos( aPos )
      ENDCASE

      oDlg:show()
      SetAppFocus( oDlg )

   ENDIF
RETURN
[/size]
But I have such a question. It displays the image in the background, i.e. outside the window from which it was called by clicking on the button, and even behind the main window of the system. Is there any way to make it display the image in the foreground?

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#7 Post by Auge_Ohr »

you can hold it "onTop"

Code: Select all

      oDlg:alwaysOnTop := .T.
      oDlg:create()
greetings by OHR
Jimmy

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#8 Post by Eugene Lutsenko »

Everything worked out fine. Thank You, Jimmy!

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#9 Post by Eugene Lutsenko »

There is another problem with using FullView(). If you press Esc when a graphic file is visible on the screen, the previous screen form from which the FullView() procedure is started is closed instead of the image window. And the image window itself is not closed. And only the window with the image of the file should be closed.

Есть еще одна проблема с использованием FullView(). Если нажать Esc, когда на экране виден графический файл, то закрывается не окно этого изображения, а предыдущая экранная форма, из которого запущена процедура FullView(). А само окно изображения при этом не закрывается. А должно закрываться только окно с изображением файла.

User avatar
Auge_Ohr
Posts: 1428
Joined: Wed Feb 24, 2010 3:44 pm

Re: Procedure FullView (cFile ) function DC_GetWorkArea()

#10 Post by Auge_Ohr »

Eugene Lutsenko wrote:There is another problem with using FullView(). If you press Esc when a graphic file is visible on the screen, the previous screen form from which the FullView() procedure is started is closed instead of the image window.
you still have no "extra" Eventloop for your XbpDialog() so it use Express++ Eventloop from Parent (which will react on ESC and close)

Code: Select all

      oDlg:show()
      SetAppFocus( oDlg )
* ------------------------------------------------------------- *
      // add this
      nEvent := 0
      WHILE nEvent != xbeP_Close
         nEvent := APPEVENT( @mp1, @mp2, @oXbp )
         DO CASE
            CASE nEvent == xbeP_Keyboard .AND. mp1 == xbeK_ESC 
                   oDlg:destroy()
                   Exit
            OTHERWISE
               oXbp:HandleEvent( nEvent, mp1, mp2 )
         ENDCASE
      ENDDO
* ------------------------------------------------------------- *
   ENDIF
RETURN
greetings by OHR
Jimmy

Post Reply