VB PrintWindow函数截取窗口有关问题
VB PrintWindow函数截取窗口问题
各位大神新年好啊,小弟有个问题想请教一下:我写了一个小程序,主要为在PictureBox绘制波形线,其中有一个功能是截取名称为“Motor Torque Monitor”窗体的画面,功能参照了一位大神的写法,截取窗体画面OK,但有个小问题

如使用软件上按钮“Manual Save Picture”,红色波形线就没有了,使用键盘上的Print Screen就可以正常截图(有红色波形线),如下

请教各位大神这个怎么改,才能使用截图功能把红线也一起保留?
截图代码参照大神的写法,如下
------解决思路----------------------
你先用Spy4Win软件确定这根红线是否属于窗口“Motor Torque Monitor”,如果属于,截图前使用SendMessage函数模拟点击按钮“Manual Save Picture”确定红线绘制完;如果不属于,截取它实际属于的那个窗口,也可能该红线根本就没有对应窗口,果真如此的话,可以试试将程序放在另创建的桌面下,然后截取改另创建桌面的图片。
CreateDesktop
The CreateDesktop function creates a new desktop on the window station associated with the calling process. It returns a handle that can be used to access the new desktop. The calling process must have an associated window station, either assigned by the system at process creation time or set by SetProcessWindowStation. A desktop is a secure object contained within a window station object. A desktop has a logical display surface and contains windows, menus, and hooks.
HDESK CreateDesktop(
LPCTSTR lpszDesktop, // name of the new desktop
LPCTSTR lpszDevice, // reserved; must be NULL.
LPDEVMODE pDevMode, // reserved; must be NULL
DWORD dwFlags, // flags to control interaction with other
// applications
DWORD dwDesiredAccess, // specifies access of returned handle
LPSECURITY_ATTRIBUTES lpsa // specifies security attributes of
// the desktop
);
Parameters
lpszDesktop
Pointer to a null-terminated string specifying the name of the desktop to be created. Desktop names are case-insensitive and may not contain backslash characters (\).
lpszDevice
Reserved; must be NULL. The desktop uses the default display driver loaded at boot time.
pDevMode
Reserved; must be NULL.
dwFlags
A bit flag parameter that controls how the calling application will cooperate with other applications on the desktop. This parameter can specify zero or the following value: Value Description
DF_ALLOWOTHERACCOUNTHOOK Allows processes running in other accounts on the desktop to set hooks in this process.
dwDesiredAccess
Specifies the access rights the returned handle has to the desktop. This parameter must include the DESKTOP_CREATEWINDOW flag because internally CreateDesktop uses the handle to create a window. In addition, you can specify any of the standard access rights, such as READ_CONTROL or WRITE_DAC, and a combination of the following desktop-specific access rights. Value Description
DESKTOP_CREATEMENU Required to create a menu on the desktop.
DESKTOP_CREATEWINDOW Required to create a window on the desktop.
DESKTOP_ENUMERATE Required for the desktop to be enumerated.
DESKTOP_HOOKCONTROL Required to establish any of the window hooks.
DESKTOP_JOURNALPLAYBACK Required to perform journal playback on the desktop.
DESKTOP_JOURNALRECORD Required to perform journal recording on the desktop.
DESKTOP_READOBJECTS Required to read objects on the desktop.
DESKTOP_SWITCHDESKTOP Required to activate the desktop using the SwitchDesktop function.
DESKTOP_WRITEOBJECTS Required to write objects on the desktop.
lpsa
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpsa is NULL, the handle cannot be inherited.
The lpSecurityDescriptor member of the structure specifies a security descriptor for the new desktop. If lpsa is NULL, the desktop inherits its security descriptor from the parent window station.
Return Values
If the function succeeds, the return value is a handle to the newly created desktop. If the specified desktop already exists, the function succeeds and returns a handle to the existing desktop. When you are finished using the handle, call the CloseDesktop function to close it.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
Remarks
The CreateDesktop function returns a handle that can be used to access the desktop.
If the dwDesiredAccess parameter specifies the READ_CONTROL, WRITE_DAC, or WRITE_OWNER standard access rights to access the security descriptor of the desktop object, you must also request the DESKTOP_READOBJECTS and DESKTOP_WRITEOBJECTS access rights.
QuickInfo
Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.
See Also
Window Stations and Desktops Overview, Window Station and Desktop Functions, CloseDesktop, SECURITY_ATTRIBUTES, SetProcessWindowStation, SwitchDesktop
------解决思路----------------------
晕,先没细看楼主的代码。
楼主无视我3F的回复就行了。

但我觉得你应该把Function SaveHwndPic( ) 中的Picture1.Refresh这句去掉。
各位大神新年好啊,小弟有个问题想请教一下:我写了一个小程序,主要为在PictureBox绘制波形线,其中有一个功能是截取名称为“Motor Torque Monitor”窗体的画面,功能参照了一位大神的写法,截取窗体画面OK,但有个小问题
如使用软件上按钮“Manual Save Picture”,红色波形线就没有了,使用键盘上的Print Screen就可以正常截图(有红色波形线),如下
请教各位大神这个怎么改,才能使用截图功能把红线也一起保留?
截图代码参照大神的写法,如下
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Private Declare Function PrintWindow Lib "user32" (ByVal SrcHwnd As Long, ByVal DesHDC As Long, ByVal uFlag As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal Hwnd As Long, lpRect As RECT) As Long '取得窗体位置的函数
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Function SaveHwndPic(Hwnd As Long, SaveFileName As String, Picture1 As PictureBox) As Boolean
On Error GoTo Err
Dim R As RECT
GetWindowRect Hwnd, R
Picture1.Width = (R.Right - R.Left) * Screen.TwipsPerPixelX
Picture1.Height = (R.Bottom - R.Top) * Screen.TwipsPerPixelY
PrintWindow Hwnd, Picture1.hDC, 0
Picture1.Refresh
SavePicture Picture1.Image, SaveFileName
SaveHwndPic = True
Exit Function
Err:
MsgBox Err.Description
Resume
End Function
Private Sub Command1_Click()
SaveHwndPic FindWindow(vbNullString, "Motor Torque Monitor"), App.Path & "\SavePicture\Test\" & SSTab1.Caption & "-" & Format(Now, "yyyymmddhhmmss") & ".jpg", Picture1
End Sub
------解决思路----------------------
你先用Spy4Win软件确定这根红线是否属于窗口“Motor Torque Monitor”,如果属于,截图前使用SendMessage函数模拟点击按钮“Manual Save Picture”确定红线绘制完;如果不属于,截取它实际属于的那个窗口,也可能该红线根本就没有对应窗口,果真如此的话,可以试试将程序放在另创建的桌面下,然后截取改另创建桌面的图片。
CreateDesktop
The CreateDesktop function creates a new desktop on the window station associated with the calling process. It returns a handle that can be used to access the new desktop. The calling process must have an associated window station, either assigned by the system at process creation time or set by SetProcessWindowStation. A desktop is a secure object contained within a window station object. A desktop has a logical display surface and contains windows, menus, and hooks.
HDESK CreateDesktop(
LPCTSTR lpszDesktop, // name of the new desktop
LPCTSTR lpszDevice, // reserved; must be NULL.
LPDEVMODE pDevMode, // reserved; must be NULL
DWORD dwFlags, // flags to control interaction with other
// applications
DWORD dwDesiredAccess, // specifies access of returned handle
LPSECURITY_ATTRIBUTES lpsa // specifies security attributes of
// the desktop
);
Parameters
lpszDesktop
Pointer to a null-terminated string specifying the name of the desktop to be created. Desktop names are case-insensitive and may not contain backslash characters (\).
lpszDevice
Reserved; must be NULL. The desktop uses the default display driver loaded at boot time.
pDevMode
Reserved; must be NULL.
dwFlags
A bit flag parameter that controls how the calling application will cooperate with other applications on the desktop. This parameter can specify zero or the following value: Value Description
DF_ALLOWOTHERACCOUNTHOOK Allows processes running in other accounts on the desktop to set hooks in this process.
dwDesiredAccess
Specifies the access rights the returned handle has to the desktop. This parameter must include the DESKTOP_CREATEWINDOW flag because internally CreateDesktop uses the handle to create a window. In addition, you can specify any of the standard access rights, such as READ_CONTROL or WRITE_DAC, and a combination of the following desktop-specific access rights. Value Description
DESKTOP_CREATEMENU Required to create a menu on the desktop.
DESKTOP_CREATEWINDOW Required to create a window on the desktop.
DESKTOP_ENUMERATE Required for the desktop to be enumerated.
DESKTOP_HOOKCONTROL Required to establish any of the window hooks.
DESKTOP_JOURNALPLAYBACK Required to perform journal playback on the desktop.
DESKTOP_JOURNALRECORD Required to perform journal recording on the desktop.
DESKTOP_READOBJECTS Required to read objects on the desktop.
DESKTOP_SWITCHDESKTOP Required to activate the desktop using the SwitchDesktop function.
DESKTOP_WRITEOBJECTS Required to write objects on the desktop.
lpsa
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpsa is NULL, the handle cannot be inherited.
The lpSecurityDescriptor member of the structure specifies a security descriptor for the new desktop. If lpsa is NULL, the desktop inherits its security descriptor from the parent window station.
Return Values
If the function succeeds, the return value is a handle to the newly created desktop. If the specified desktop already exists, the function succeeds and returns a handle to the existing desktop. When you are finished using the handle, call the CloseDesktop function to close it.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
Remarks
The CreateDesktop function returns a handle that can be used to access the desktop.
If the dwDesiredAccess parameter specifies the READ_CONTROL, WRITE_DAC, or WRITE_OWNER standard access rights to access the security descriptor of the desktop object, you must also request the DESKTOP_READOBJECTS and DESKTOP_WRITEOBJECTS access rights.
QuickInfo
Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.
See Also
Window Stations and Desktops Overview, Window Station and Desktop Functions, CloseDesktop, SECURITY_ATTRIBUTES, SetProcessWindowStation, SwitchDesktop
------解决思路----------------------
晕,先没细看楼主的代码。
楼主无视我3F的回复就行了。
但我觉得你应该把Function SaveHwndPic( ) 中的Picture1.Refresh这句去掉。