Saving screenshots of open Windows with graphic files

This forum is for eXpress++ general support.
Message
Author
User avatar
Tom
Posts: 1170
Joined: Thu Jan 28, 2010 12:59 am
Location: Berlin, Germany

Re: Saving screenshots of open Windows with graphic files

#21 Post by Tom »

Hi, Eugene.

DC_Scrn2ClipBoard() without any parameter saves the SetAppWindow() to the clipboard. Use the object containing the dialog you want to save (first parameter).

If you want the contens of a dialog instead of the dialog with menu a.s.o., use the drawingarea (oDialog:DrawingArea). If you only want the to browses, it's getting difficult, since they are on the dialog together with the buttons. If you save the screen for the drawingarea, you also get the buttons. Two possible solutions: You change DC_Scrn2Clipboard so it understands an area rectangle (pos and size) or you place the two browses on a static you can use for saving the screen. Third solution: You use the dialog object and cut out the browses from the picture.
Best regards,
Tom

"Did I offend you?"
"No."
"Okay, give me a second chance."

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

Re: Saving screenshots of open Windows with graphic files

#22 Post by Auge_Ohr »

hi, Tom
Tom wrote:DC_Scrn2ClipBoard() without any parameter saves the SetAppWindow() to the clipboard.
does DC_Scrn2ClipBoard() without Parameter still work under Windows 10 ?

it use keybd_event()

Code: Select all

DLLFUNCTION keybd_event(mvkey, nscan, flags, xtra) USING STDCALL FROM USER32.DLL
which is IMHO deprecated.
as i know Keyboard and Mouse now use SendInput() API function

Code: Select all

FUNCTION Print_Window( nWindow )
LOCAL oInput := INPUT() :New()                                  // ot4xb Structure
LOCAL nSize  := oInput:_sizeof_()
LOCAL nRet   := 0

   nWindow := IIF( EMPTY( nWindow ), 0, 1 )                 // 0 is entire screen, 1 is active window
   sleep( 10 )

   // deprecated, does not work under Windows 10
   // keybd_Event( VK_SNAPSHOT,nWindow,0,0)

   oInput:type := INPUT_KEYBOARD
   oInput:ki:wVk := VK_SNAPSHOT
   oInput:ki:wScan := nWindow
   oInput:ki:dwFlags := 0
   oInput:ki:dwExtraInfo := 0
   // now use SendInput API Function
   nRet := @user32:SendInput( 1, oInput, nSize )

RETURN nRet
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: Saving screenshots of open Windows with graphic files

#23 Post by Eugene Lutsenko »

Hi, Jimmy!

So what would the function for w7 & w10 look like if it saved an active window to a file?

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

Re: Saving screenshots of open Windows with graphic files

#24 Post by Auge_Ohr »

Eugene Lutsenko wrote:So what would the function for w7 & w10 look like if it saved an active window to a file?

Code: Select all

Print_Window( 0 )	// 0 is entire screen
Print_Window( 1 )	// 1 is active window
but that is only Keyboard Stuff to activate Clipboard :!:

SendInput()*** can return Error Level like XbpClipBoard():open() --> lSuccess this Way

Code: Select all

   nRet := @user32:SendInput( 1, oInput, nSize )
RETURN IF(nRet<>0,.T.,.F.)
but you still have "open" Clipboard and transfer data into you App.

with Xbase++ you normal can use GraBitBlt() or oBMP:Draw() to create a new Bitmap from Object like FUNCTION GraSaveScreen()

---

Clipboard need Exclusive Access but play Video might use much CPU so i need a Thread to try more than once.

i use it to capture from Video-Overlay so i need "print Screen" and Clipboard in a Thread CLASS

Code: Select all

   // "print Screen" CLASS  
   oPrntScrn := PrnScr2BMP() :new()
   oPrntScrn:aoChild := aoChild
   oPrntScrn:start()
   // Set Focus on Object
   SETAPPFOCUS( aoChild[ CH_WMP ] )
   IF Print_Window( 1 ) = 0
      DO WHILE oPrntScrn:lReady = .F.
         nFail ++
         IF ( nFail % 100 ) = 0
            // same again
            SETAPPFOCUS( aoChild[ CH_WMP ] )
            Print_Window( 1 )
         ELSEIF nFail > nTimeout
            EXIT
         ENDIF
         SLEEP( 1 )
      ENDDO
   ENDIF
   IF nFail > nTimeout
   ELSE
      oThumb := oPrntScrn:oOutBMP
   ENDIF
*** https://msdn.microsoft.com/de-de/librar ... s.85).aspx
Return value

Type: UINT

The function returns the number of events that it successfully inserted into the keyboard or mouse input stream.
If the function returns zero, the input was already blocked by another thread. To get extended error information,
call GetLastError.

This function fails when it is blocked by UIPI.
Note that neither GetLastError nor the return value will indicate the failure was caused by UIPI blocking.
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: Saving screenshots of open Windows with graphic files

#25 Post by Eugene Lutsenko »

Jimmy! Could you please give an option of this feature for w7:

Code: Select all

FUNCTION Print_Window (nWindow) 
LOCAL oInput: = INPUT (): New () // ot4xb Структура 
LOCAL nSize: = oInput: _sizeof_ () 
LOCAL nRet: = 0 

   nWindow: = IIF (EMPTY (nWindow), 0, 1) // 0 - полный экран, 1 - активное окно 
   sleep (10) 

   // устарело, не работает под Windows 10 
   // keybd_Event (VK_SNAPSHOT, nWindow, 0,0) 

   oInput: type: = INPUT_KEYBOARD 
   oInput: ki: wVk: = VK_SNAPSHOT 
   oInput : ki: wScan: = nWindow 
   oInput: ki: dwFlags: = 0 
   oInput: ki: dwExtraInfo: = 0 
   // теперь использовать API-интерфейс SendInput 
   nRet: = @ user32: SendInput (1, oInput, nSize) 

RETURN nRet
[/size]

User avatar
Tom
Posts: 1170
Joined: Thu Jan 28, 2010 12:59 am
Location: Berlin, Germany

Re: Saving screenshots of open Windows with graphic files

#26 Post by Tom »

Hi, Jimmy.

DC_Scrn2ClipBoard() works with all Windows versions, since the "<PrintScrn>" key, which is used here, works with all Windows versions. BUT. If you hand an object name to DC_Scrn2Clipboard, like DC_Scrn2Clipboard(oDialog), DC_Scrn2Clipboard(oDialog:DrawingArea), DC_Scrn2Clipboard(oBrowse) and so on, it uses the GraSaveScreen function from the Xbase++ samples (in _DCxButt.PRG of the eXpress++ sources). That one uses GraBitBlt to copy a screen/object area to a bitmap object and copies that one to the clipboard. This also works with all Windows versions - and without strange API calls. ;)
Best regards,
Tom

"Did I offend you?"
"No."
"Okay, give me a second chance."

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

Re: Saving screenshots of open Windows with graphic files

#27 Post by Auge_Ohr »

hi,
Tom wrote:DC_Scrn2ClipBoard() works with all Windows versions, since the "<PrintScrn>" key, which is used here, works with all Windows versions
i know "Printscreen" which work with every Windows Version but i talk about keybd_event and mouse_event which are deprecated.
Note This function has been superseded. Use SendInput instead.
https://msdn.microsoft.com/de-de/librar ... s.85).aspx
https://msdn.microsoft.com/de-de/librar ... s.85).aspx
greetings by OHR
Jimmy

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

Re: Saving screenshots of open Windows with graphic files

#28 Post by Auge_Ohr »

Eugene Lutsenko wrote:Jimmy! Could you please give an option of this feature for w7:
as i have answer Tom i just talk about DC_Scrn2ClipBoard() without Parameter while it use keybd_event API function.
i know that mouse_event API function does not work any more under Windows 10 so i ask if keybd_event API function still work.
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: Saving screenshots of open Windows with graphic files

#29 Post by Eugene Lutsenko »

is there any way to make the command:

Code: Select all

 @1,DCGUI_COL+d DCPUSHBUTTON CAPTION 'PrtScr' SIZE LEN('PrtScr'), 1.5 ACTION {||SaveScreenAsFile(Disk_dir+'/Aid_data/Screenshots/F1_4.jpg'), DC_GetRefresh(GetList)} PARENT oGroup1
[/size]
run once without pressing a key?

This works correctly but requires pressing a key on the button:

Code: Select all

/* ----- Create ToolBar ----- */

mStr1 = L('Помощь')                                  ;mStr1Len = LEN(mStr1)
mStr2 = L('1.Выбрать язык текущим')                  ;mStr2Len = LEN(mStr2)
mStr3 = L('2.Выбрать язык текущим и сделать перевод');mStr3Len = LEN(mStr3)
mStr4 = L('3.Создать все языковые базы')             ;mStr4Len = LEN(mStr4)

 d    = 7                                                                                                                   
 n    = 1.5                                                                                                                   
 mL   = 20
 mK   = 0.3

*PRIVATE PrtScrBlock:={||SaveScreenAsFile(Disk_dir+'/Aid_data/Screenshots/F1_4.jpg')}  // Клиффорд

 @ 43, 0           DCGROUP oGroup1 CAPTION L(' ') SIZE 137, 3.0
 @  1, 1           DCPUSHBUTTON    CAPTION mStr1 SIZE mStr1Len+(mL-mStr1Len)*mK+n, 1.5 ACTION {||Help14(), DC_GetRefresh(GetList)}                                  PARENT oGroup1
 @  1, DCGUI_COL+d DCPUSHBUTTON    CAPTION mStr2 SIZE mStr2Len+(mL-mStr2Len)*mK+n, 1.5 ACTION {||SelectLang(1, Languages->ISO639_1,'один'), DC_GetRefresh(GetList)} PARENT oGroup1
 @  1, DCGUI_COL+d DCPUSHBUTTON    CAPTION mStr3 SIZE mStr3Len+(mL-mStr3Len)*mK+n, 1.5 ACTION {||SelectLang(0, Languages->ISO639_1,'один'), DC_GetRefresh(GetList)} PARENT oGroup1
 @  1, DCGUI_COL+d DCPUSHBUTTON    CAPTION mStr4 SIZE mStr4Len+(mL-mStr4Len)*mK+n, 1.5 ACTION {||CreateAllLangBases(),                      DC_GetRefresh(GetList)} PARENT oGroup1

 @  1, DCGUI_COL+d DCPUSHBUTTON    CAPTION 'PrtScr' SIZE LEN('PrtScr'), 1.5 ACTION {||SaveScreenAsFile(Disk_dir+'/Aid_data/Screenshots/F1_4.jpg'), DC_GetRefresh(GetList)} PARENT oGroup1

****** Отображение таблицы ***************

DCSETPARENT TO

@ 5, 0 DCBROWSE oBrowse ALIAS 'Languages' SIZE 137,38 ;
       PRESENTATION DC_BrowPres() ;       // Только просмотр БД
       NOSOFTTRACK ;
       HEADLINES 2 ;                      // Кол-во строк в заголовке (перенос строки - ";")
       SCOPE ;
       ITEMMARKED bItems;
       COLOR {||IIF(LEN(ALLTRIM(Languages->SELECT))>0, {nil,aColor[153]}, IIF(Languages->APPEALS>0, {nil,aColor[39]}, {nil,GRA_CLR_WHITE}))}

*DCSETPARENT oBrowse

 DCGETOPTIONS TABSTOP

*** Подарок от Роджера

DCBROWSECOL FIELD Languages->LANGCODE HEADER L("Lang;Code" )        PARENT oBrowse WIDTH 4
DCBROWSECOL FIELD Languages->SELECT   HEADER L("Current;language" ) PARENT oBrowse WIDTH 10 
DCBROWSECOL FIELD Languages->LANGUAGE HEADER L("ISO language name") PARENT oBrowse WIDTH 52
DCBROWSECOL FIELD Languages->APPEALS  HEADER L("Number;appeals"   ) PARENT oBrowse WIDTH 10
DCBROWSECOL FIELD Languages->ISO639_1 HEADER L("ISO;639-1"        ) PARENT oBrowse WIDTH 6

DCGETOPTIONS SAYFONT '10.Helv Bold' TABSTOP AUTORESIZE

* DCGET OPTION CLOSEQUERY MSG {|| SaveScreenToFile(...), .T. }

DCREAD GUI ;
   FIT ;
   OPTIONS GetOptions ;
   MODAL ;
   SetAppWindow;
   TITLE L('1.4. Выбор текущего языка интерфейса системы "Эйдос-Х++"');
   CLEAREVENTS
*  EVAL PrtScrBlock
*  EVAL {|o|SetAppFocus(oBrowse:GetColumn(1))};
[/size]
I tried different other options, including code blocks. But it copies everything, not just the image of the current window.

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

Re: Saving screenshots of open Windows with graphic files

#30 Post by rdonnay »

Do this:

Code: Select all

bSaveScreen := {||SaveScreenAsFile(Disk_dir+'/Aid_data/Screenshots/F1_4.jpg'), DC_GetRefresh(GetList)}

...... 

 @1,DCGUI_COL+d DCPUSHBUTTON CAPTION 'PrtScr' SIZE LEN('PrtScr'), 1.5 ACTION  bSaveScreen PARENT oGroup1

......

DCREAD GUI ... EVAL bSaveScreen
The eXpress train is coming - and it has more cars.

Post Reply