-
Dec 5th, 2018, 04:10 PM
#1
Thread Starter
Lively Member
[RESOLVED] How to save picture image graphics & controls to a file
I have perused through many previous topics on this subject and cannot find a solution. But I don't believe my problem is unique.
I have a form with a small picture box called picGraph which is a predefined graph area box with lines and various labels. The bottom horizontal line is the x axis. The sides are y axis. From some engineering calculations, I draw in the box some x y data points. Each data point gets a small circle and a line drawn from point to point going left to right in the box. Under the x axis is a label with each x value. Expanded output data is listed in separate labels.
I set autoredraw true and do a set picGaph.Picture = picGraph,image and SavePicture.picGraph "filename...etc"
The picture that gets saved contains only the graphics that were drawn(circles and connecting lines) The predefined controls(lines, labels) are completely missing.
I hope there is a simple solution to doing this. I thought about doing a screen save and then cropping out only the picGraph area from the form, but that seems like overkill to me.
Why is this so complicated?
There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!
Richard P. Feynman
-
Dec 5th, 2018, 08:46 PM
#2
Addicted Member
Re: How to save picture image graphics & controls to a file
Hi,
What about capturing your screen as needed and save it to a image?
This is a great example of capturing screens, perhaps it may help you with some modifications.
http://www.thescarms.com/VBasic/capture.aspx
-
Dec 5th, 2018, 11:42 PM
#3
Thread Starter
Lively Member
Re: How to save picture image graphics & controls to a file
Hello. Without looking at your link yet, I will just reply that a screen shot will show everything on the form and all I want is about 1/10th of that.. That means going to Paint and cropping it out. Not very professional.
I will spend some time and look at your code now.
There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!
Richard P. Feynman
-
Dec 6th, 2018, 01:07 AM
#4
Re: How to save picture image graphics & controls to a file
check the api printscreen, could be helpful, but cropping is required if u r not taking the entire client area. if u know the rect it should not be hard to do.
or, learn how to draw directly into the dc without using labels and shapes, doing so u can just do a bitblt.
-
Dec 6th, 2018, 03:18 AM
#5
Re: How to save picture image graphics & controls to a file
Hello. There is another option.
This option also works when the window to capture is not visible on the screen:
It needs an auxiliary PictureBox that should be Visible = False
Code:
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const SWP_NOACTIVATE = &H10&
Private Const SWP_NOMOVE As Long = &H2
Private Const SWP_NOZORDER = &H4
Private Const WM_PAINT = &HF
Private Const WM_PRINT = &H317
Private Const PRF_CHILDREN = &H10&
Private Const PRF_CLIENT = &H4&
Private Const PRF_OWNED = &H20&
'This function returns the image of a window with its controls
Public Function GetWindowImage(nHwnd As Long, nPicAux As PictureBox) As StdPicture
Dim iRc As RECT
' nPicAux size:
GetWindowRect nHwnd, iRc
SetWindowPos nPicAux.hWnd, 0, 0, 0, iRc.Right - iRc.Left, iRc.Bottom - iRc.Top, SWP_NOZORDER Or SWP_NOMOVE Or SWP_NOACTIVATE
nPicAux.AutoRedraw = True
' capture the image
SendMessage nHwnd, WM_PAINT, nPicAux.hDC, 0
SendMessage nHwnd, WM_PRINT, nPicAux.hDC, PRF_CHILDREN Or PRF_CLIENT Or PRF_OWNED
' set the return variable
Set GetWindowImage = nPicAux.Image
nPicAux.Cls
End Function
The auxiliary PictureBox is named picAux in the sample usage:
Code:
SavePicture GetWindowImage(picGraph.hWnd, picAux), "d:\test.bmp"
Last edited by Eduardo-; Dec 6th, 2018 at 03:27 AM.
-
Dec 6th, 2018, 01:33 PM
#6
Re: How to save picture image graphics & controls to a file
What Eduardo- posted is what I was thinking would be the proper way of having the picuturebox paint itself and child controls into a graphical image.
But, there is a fairly simple way to capture a portion of the desktop, which I normally use with a hidden form, but could be done with a picturebox as well.
With AutoRedraw set to True, the hDC refers to the .Image memory drawing context.
With AutoRedraw set to False, the hDC refers to the screen area "above" (in Zorder) of the client area of the picturebox.
So, if you want to capture the screen area of the picturebox, you could just set AutoRedraw to False (temporarily if you want), then bitblt from the source picturebox to another hDC with a bitmap (in my example I use a second, hidden picturebox for convenience).
You can then save the bitmap drawn into.
Since you need to specify height and width in pixels to bitblt, you need to either convert your pictureboxes values to pixels, or just change the scalemode to pixels (can also be done temporarily, if you need to draw in different scale).
Some of the lines in the example below, could be preset rather than be in this code, if it doesn't need to change, i.e. the size of picturebox2 and its scalemode and autoredraw state.
Code:
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, _
ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _
ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Sub Command1_Click()
Picture1.AutoRedraw = False
Picture2.Width = Picture1.Width
Picture2.Height = Picture1.Height
Picture2.AutoRedraw = True
Picture1.ScaleMode = vbPixels
BitBlt Picture2.hDC, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, Picture1.hDC, 0, 0, vbSrcCopy
SavePicture Picture2.Image, "c:\c\tst1.bmp"
End Sub
-
Dec 6th, 2018, 02:26 PM
#7
Re: How to save picture image graphics & controls to a file
The disadvantage of capturing the desktop image is that the window to capture is required to be visible (fully visible) on the screen.
-
Dec 6th, 2018, 07:14 PM
#8
Thread Starter
Lively Member
Re: How to save picture image graphics & controls to a file
Thanks all. I'm willing to try these methods. But now it occurred to me, why am I using a picture box for this application?
I could just as well draw lines and circles on a form or frame. All I want to do is save the image that is showing on the screen, and if some other container is more usable then I could just as well use that one. Is it just the picture box control holding me up?
There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!
Richard P. Feynman
-
Dec 6th, 2018, 07:44 PM
#9
Thread Starter
Lively Member
Re: How to save picture image graphics & controls to a file
The code from passel works like a charm! Simple and concise-I like that. I'm going to incorporate this into the other "malfunctioning" screen prints I've been constantly repairing.
There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!
Richard P. Feynman
-
Dec 6th, 2018, 10:03 PM
#10
Thread Starter
Lively Member
Re: How to save picture image graphics & controls to a file
Ok, I added this code to another form and some problems. First: never make picture1 the container for picture2! Don't ask.
Also, the scalemode needs to be reset back to original before exiting.
On my new form/picture, I use scaling to draw X/Y axis and structure around it. When I return from creating the file, my scaling is lost even tho I restore the scalewidth and scaleheight values back. So I just close the form before exiting but the user then has to reopen it.
Leaving this open for a few days just in case of any abnormalities.
There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!
Richard P. Feynman
-
Dec 6th, 2018, 10:41 PM
#11
Re: How to save picture image graphics & controls to a file
Originally Posted by VB-only
When I return from creating the file, my scaling is lost even tho I restore the scalewidth and scaleheight values back.
Hi VB-only,
That seems strange to me. I use the PictureBox in many different ways, and I've never had a problem with it losing the scaling. And, there are several places where I change the ScaleMode to vbPixels, do something and then restore the ScaleWidth and ScaleHeight (of course, saving them before I set ScaleMode to vbPixels). If you could show us a code-snippet, maybe we could figure out what's going on. I've never had to reload a form just to get the PictureBox to start working correctly again.
Something else that comes to mind is the idea that a form's user-interface is something different from the form's code/COM object. You may be unload the form, but not uninstantiating the form's code/COM object, which is easy to do. Maybe you have some module level (or maybe local static) variables that are fouling you up. That's just shots-in-the-dark. Some code would help determine that. Maybe show us how you're loading/unloading this form from some other external code as well.
Good Luck,
Elroy
EDIT1: Another thought is, once you custom-set your ScaleWidth and ScaleHeight, you can't further tamper with ScaleMode other than setting it to vbUser (which it will do automatically). Setting it to anything else will override your ScaleWidth and ScaleHeight settings.
EDIT2: Also, when restoring a PictureBox's scale, you really need to save all three of ScaleWidth, ScaleHeight, and ScaleMode. If ScaleMode is anything other than vbUser, just restore ScaleMode and you're done. If ScaleMode is vbUser, just restore ScaleWidth and ScaleHeight (leaving ScaleMode alone) and you're done. In that last case, it'll auto-set to vbUser.
Last edited by Elroy; Dec 6th, 2018 at 10:53 PM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Dec 6th, 2018, 11:00 PM
#12
Re: How to save picture image graphics & controls to a file
One does not really need to "copy over" to a helper-PicBox -
just "deep-refreshing" the original PicBox is enough - the following code shows that:
Code:
Option Explicit
Private Declare Function SendMessageW& Lib "user32" (ByVal hwnd&, ByVal wMsg&, ByVal wParam&, ByVal lParam&)
Private Sub Form_Load()
Picture1.Line (0, 0)-(2400, 1200), vbGreen, B
Label1.AutoSize = True: Label1.Caption = Now
End Sub
Private Sub Form_Click()
Set Me.Picture = RefreshPicImage(Picture1)
End Sub
Public Function RefreshPicImage(P As PictureBox) As StdPicture
P.AutoRedraw = True
SendMessageW P.hwnd, &HF, P.hDC, 0 'send a WM_PAINT
Set RefreshPicImage = P.Image 'and return the refreshed Image
End Function
Below is the result, as it happens after a Form_Click
(the Picture1 is sitting at the right-hand-side - and got at design-time a Label + a BG-Picture -
the green rectangle is drawn "live" at Form_Load).
HTH
Olaf
-
Dec 6th, 2018, 11:18 PM
#13
Re: How to save picture image graphics & controls to a file
Forgot to mention, that the ChartCanvas-PicBox needs to have AutoRedraw = True for the above approach to work properly -
here's another example, which takes care of that (The Form needs a Picture1 and a Label1 on it).
Code:
Option Explicit
Private Declare Function SendMessageW& Lib "user32" (ByVal hwnd&, ByVal wMsg&, ByVal wParam&, ByVal lParam&)
Private Sub Form_Load()
Picture1.AutoRedraw = True 'this is necessary (but usually the case with flicker-free PicBox-canvases)
Label1.AutoSize = True
End Sub
Private Sub Form_Click()
RedrawChart
Set Me.Picture = RefreshPicImage(Picture1)
End Sub
Private Sub RedrawChart() 'just to simulate some actions (drawings and also refreshing the "statics")
Picture1.Cls
Picture1.Line (0, 0)-(2400, 1200), vbGreen, B
Label1.Caption = Now
End Sub
Public Function RefreshPicImage(P As PictureBox) As StdPicture
SendMessageW P.hwnd, &HF, P.hDC, 0 'send a WM_PAINT
Set RefreshPicImage = P.Image 'and return the refreshed Image
End Function
Olaf
-
Dec 7th, 2018, 02:21 AM
#14
Re: How to save picture image graphics & controls to a file
-
Dec 7th, 2018, 05:54 AM
#15
Re: How to save picture image graphics & controls to a file
Originally Posted by The trick
PrintWindow
Ah - right, that looks nicer than the SendMessage-call -
and works for the "self-deep-refresh" as well...
Code:
Private Declare Function PrintWindow& Lib "user32" (ByVal hWnd&, ByVal hDC&, Optional ByVal Flags& = 1)
Public Function RefreshPicImage(P As PictureBox) As StdPicture
PrintWindow P.hWnd, P.hDC
Set RefreshPicImage = P.Image 'and return the refreshed Image
End Function
Olaf
-
Dec 7th, 2018, 07:18 AM
#16
Re: How to save picture image graphics & controls to a file
PrintWindow API is actually implemented by sending wnd messages underneath:
Originally Posted by MSDN
The application that owns the window referenced by hWnd processes the PrintWindow call and renders the image in the device context that is referenced by hdcBlt. The application receives a WM_PRINT message or, if the PW_PRINTCLIENT flag is specified, a WM_PRINTCLIENT message. For more information, see WM_PRINT and WM_PRINTCLIENT.
. . . i.e. might fail if custom-control does not impl WM_PRINT/WM_PRINTCLIENT. Sending an hDC in wParam on WM_PAINT is undocumented but is usually implemented by wnd classes that implement WM_PRINTCLIENT so both methods IMO are equally viable (or "unviable").
cheers,
</wqw>
-
Dec 7th, 2018, 08:52 PM
#17
Fanatic Member
Re: How to save picture image graphics & controls to a file
Originally Posted by wqweto
PrintWindow API is actually implemented by sending wnd messages underneath:
. . . i.e. might fail if custom-control does not impl WM_PRINT/WM_PRINTCLIENT. Sending an hDC in wParam on WM_PAINT is undocumented but is usually implemented by wnd classes that implement WM_PRINTCLIENT so both methods IMO are equally viable (or "unviable").
cheers,
</wqw>
if the window is minimized,how capture the picture?
-
Dec 8th, 2018, 03:07 AM
#18
Re: How to save picture image graphics & controls to a file
Originally Posted by xxdoc123
if the window is minimized,how capture the picture?
Try maximizing before calling PrintWindow
cheers,
</wqw>
-
Dec 8th, 2018, 08:44 AM
#19
Thread Starter
Lively Member
Re: How to save picture image graphics & controls to a file
Sorry but I have sort of lost track of what is being stated here. How does this end up saving my picture control to a file(.bmp)?
There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!
Richard P. Feynman
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|