Silverfrost Forums

Welcome to our forums

Is there a need for this capability?

29 Mar 2021 2:05 #27354

Bill

Here is a sample of what you can do at the moment. Can you post a similar program that illustrates what you want.

 WINAPP
 USE clrwin
 INTEGER hres,vres,nbbp,ercode,hdib,ctrl,i
 CHARACTER(*),PARAMETER :: file = 'guest.bmp'
 CALL get_dib_size@(file,hres,vres,nbbp,ercode)
 IF(ercode /= 0)THEN; i = winio@('get_dib_size@ error'); STOP; ENDIF  
 hdib = import_bmp@(file,ercode)
 IF(ercode /= 0)THEN; i = winio@('import_bmp@ error'); STOP; ENDIF  
 i = winio@('%gr[rgb_colours]%lw',hres,vres,ctrl)
 ercode = dib_paint@(0,0,hdib,0,0)
 IF(ercode == 0)THEN; i = winio@('dib_paint@ error'); STOP; ENDIF  
 call draw_line_between@(0,0,hres,vres,RGB@(255,0,0))
 i = export_image@('guest1.png')
 IF(ercode == 0) i = winio@('export_image@ error')
 CALL release_screen_dib@(hdib)
 END
30 Mar 2021 10:50 #27371

Paul,

I see what you have done by creating a window into which the image from a file is written,. then modified, and written to a PNG.

While I have not tried it, I would imagine that this technique would work with the clipboard image. I would also imagine that I could create the window as invisible to prevent the 'flash' of the image to the user.

I will give this a try. I look at this as a stop-gap method, and your description of this in your code is much appreciated!

Thanks, Paul, Bill

30 Mar 2021 11:08 #27372

This does work well with the clipboard image. I did have to add a %ww[invisible] to prevent the 'flash' of the graphics area to the user.

Thanks, Paul, for helping me better understand these capabilities, and an alternate way to get the job done!

Bill

31 Mar 2021 6:32 #27373

Bill

My purpose in posting the program was to ask you to modify it and post it back in a the form that you would like it to work. It wasn't clear to me what you were asking for. You can make up and write in the name of a new ClearWin+ routine if that is what is needed.

31 Mar 2021 2:15 #27376

This would be how I would like to see it work with the simulated keystrokes and clipboard being used for the image source:

        call keybd_event(VK_MENU,       z'45', KEYEVENTF_EXTENDEDKEY, 0)!; //Alt Press
        call keybd_event(VK_SNAPSHOT,z'45', KEYEVENTF_EXTENDEDKEY, 0)!; //PrntScrn Press
        call keybd_event(VK_SNAPSHOT,z'45', KEYEVENTF_KEYUP+KEYEVENTF_EXTENDEDKEY,   0)!; //PrntScrn Release
        call keybd_event(VK_MENU,       z'45', KEYEVENTF_KEYUP+KEYEVENTF_EXTENDEDKEY,   0)!; //Alt Release

        call set_cursor_waiting@(1)
        call sleep1@(2.0) ! sleep long enough to allow the image to be grabbed from the open window
        call set_cursor_waiting@(0)

        my_error=sizeof_clipboard_bitmap@(actual_width,actual_height) ! will detect if the capture actually did work
        if(my_error.ne.0) then ! the capture worked
                if(clipboard_to_screen_block@(hdib).ne.0) then ! this does the grab into local memory
                        call export_png@(hdib,NEW_FILENAME,my_error) ! **** this is the routine that I would like to see ****
                        call release_screen_dib@(hdib) ! release the memory
                endif
        endif
31 Mar 2021 3:36 #27377

Bill

Here is a way to do it with the existing routines...

        use clrwin
        integer, parameter::grhandle = 42
        integer(7) hdib
        integer actual_width,actual_height,my_error
        my_error=sizeof_clipboard_bitmap@(actual_width,actual_height)
        if(my_error.ne.0) then
           if(clipboard_to_screen_block@(hdib).ne.0) then 
              my_error = create_graphics_region@(grhandle, actual_width,actual_height)
              my_error = dib_paint@(0,0,hdib,0,0)
              my_error = export_image@('image.png')
              my_error = delete_graphics_region@(grhandle)
              call release_screen_dib@(hdib)
           endif
        endif
        end
31 Mar 2021 3:45 #27378

Awesome! I'll give this a try today.

I would have not come up with this on my own; thank you for taking the time! I also hope it saves you additional work; I perceive you are busy enough as it is.

Thanks! Bill

31 Mar 2021 4:02 #27379

P.S. Is the grhandle=42 a literary reference?

31 Mar 2021 5:38 #27380

Paul, Can you for simplicity create separate function copy_entire_graphics_screen_to_clipboard@ or i miss something and it exists already?

31 Mar 2021 6:19 #27381

Dan

There is no such routine at the moment.

It would be possible to put Bill's method into a ClearWin+ routine but it is generally not good practice to highjack the user's clipboard. It would be necessary to copy the clipboard and restore it after use.

It appears that screen capture can be done directly in other contexts but not in C and the Windows API which is what ClearWin+ uses.

1 Apr 2021 11:24 #27383

Here is the latest update on this subject. There is an undocumented function called grab_desktop_dib@ that avoids the need to use the clipboard. It works for 32 bits but not for 64 bits at the moment.

        use clrwin
        integer, parameter::grhandle = 42
        integer(7) hdib
        integer actual_width,actual_height,my_error
        actual_width = clearwin_info@('SCREEN_WIDTH')
        actual_height = clearwin_info@('SCREEN_DEPTH')
        call grab_desktop_dib@(hdib,0,0,actual_width,actual_height)
        my_error = create_graphics_region@(grhandle,actual_width,actual_height)
        my_error = dib_paint@(0,0,hdib,0,0)
        my_error = export_image@('image42.png')
        my_error = delete_graphics_region@(grhandle)
        call release_screen_dib@(hdib)
        end
1 Apr 2021 1:33 #27389

ClearWin+ has now been fixed so that the above sample will work for 64 bits as well as for 32 bits. Updated DLLs are available on request for users of v8.70.

2 Apr 2021 11:25 #27391

Looks interesting. One question: is it possible with this method to save just the selected portion of the entire screen ? PrintScreen button started to offer recently such capability: you hit the PrintScreen and the monitor screen gets grayed and offer you to select the region to save

3 Apr 2021 1:48 #27392

As far as grabbing the entire desktop, I think this is a great functionality to have, but does not satisfy the requirement that I have imposed so that I can grab a window and not have to select it (using the Windows snapshot function) or edit it (as I would for a full desktop grab). It is a function of convenience. Keystroke: done and saved.

One could debate that the ability to grab a window programmatically by the user does take control of the clipboard and changes the contents, but if you already would have done it anyway using a Windows Snapshot or Alt+PrntScrn, there is no additional harm done by doing this programmatically.

I have seen (MSDN documentation) that it is possible to dig deep into device contexts in Windows to grab video memory that shows the current window, but it exceeds both my expertise and willingness to invest time.

3 Apr 2021 4:31 #27393

Bill

I have added a routine that exports an image of a given window and I will provide details shortly (probably Monday).

3 Apr 2021 6:13 #27394

Awesome, Paul! Looking forward to giving it a try!

3 Apr 2021 7:29 #27395

I use for videorecording nice program called Snaggit (right now it does not matter if this program is good or bad and it is not about making videorecording functionality) and what it doing really handy is that after you start it - it offers you to select one of many your open windows with mouse by highlighting each window when you move your mouse over the screen. As soon as you click on the window you want, it grabs the position of the window and the video recording starts. Same actions are for the photo recording. Same windows selection functionality with Clearwin would be great. You can then grab series if still images of specific window during the program run and later user with different software could make a movies out of them. This Clearwin function would ask you to select the window you want and then all next times it will be called it will use this selection without asking

5 Apr 2021 3:08 #27405

Bill

Here is a sample program that illustrates what you will be able to do with the updated ClearWin+....

module mymod
  use clrwin
  integer(7) hwnd
contains
integer function export()
  iw = export_window_image@(hwnd,'image.png',0_3)
  export = 2
end function
end module

winapp
program main
 use mymod
 iw = winio@('%ca[Capture Window Image]&')
 iw = winio@('%hw&',hwnd)
 iw = winio@('%cn%^bb[Export]', export)
end program

export_window_image@ uses the HWND of the current window and exports its image to the given file. The third argument is reserved and must be zero.

5 Apr 2021 3:18 #27406

Dan

Your request posed an interesting challenge. The following program illustrates what will be possible with an updated ClearWin+. It presents a symbol. When you drag this symbol and drop it over a window then an image of that window is copied to the speciified file.

module mymod
  use mswin
  integer(7) hMain,hStatus
  logical mouseDown
contains
integer function find()
  integer(7) hOld,hCur
  mouseDown = .true.
  hCur = SetCursor(LoadResource@('find','Cursor'))
  hOld = SetCapture(hMain)
  find = 3
end function

integer function export()
  integer(7) hThis,hfgrd,hCur
  logical L
  mouseDown = .false.
  L      = ReleaseCapture()
  hCur   = SetCursor(LoadResource@('Arrow','Cursor'))
  hThis  = WindowAtCursor@(0_3) 
  hfgrd  = GetForegroundWindow()
  L      = BringWindowToTop(hThis)
  iw     = export_window_image@(hThis,'image.png',0_3)
  L      = BringWindowToTop(hfgrd)
  call set_status_text@(hStatus, 0, ' Window image saved to image.png')
  export = 3
end function

integer function move()
  integer pos(2)
  character(40) txt
  logical L
  if(mouseDown)then
    L  = GetCursorPos(pos)
    write(txt, '('(',i4,',',i4,')')') pos
    call set_status_text@(hStatus, 0, trim(txt))
  else
    call set_status_text@(hStatus, 0, 'Drag the symbol to capture a window image')
  endif  
  move = 3
end function
end module mymod

winapp
use mymod
mouseDown = .false.
iw = winio@('%ca[Capture Window Image]&')
iw = winio@('%mg&', WM_LBUTTONDOWN, find)
iw = winio@('%mg&', WM_LBUTTONUP,   export)
iw = winio@('%mg&', WM_MOUSEMOVE,   move)
iw = winio@('%sb%lc&', hStatus)
iw = winio@('%hw&', hMain)
iw = winio@('%cn%`bm[static]&', LoadResource@('capture','Bitmap'))
iw = winio@('%ff%nl%cn%6bb[Close]')
end

resources
find    CURSOR find.cur
capture BITMAP capture.bmp
5 Apr 2021 5:21 #27409

Paul, this would be perfect for me.

Thanks, I shall await the updated Clearwin+!

Bill

Please login to reply.