|
if somthing else has it hooked already it will error out if you have it set to global.
what hook are you trying to use?
|
|
|
|
|
I'm trying to set a CBT global hook...how can I check if something else is has already set a CBT hook?
Are you sure this is why I keep getting errors?
I tried the same code and only changed the hook constant from WH_CBT to WH_KEYBOARD_LL or WH_MOUSE_LL and it works fine on the global system.
However, I keep getting the error with the WH_CBT ...
|
|
|
|
|
WH_CBT Hook
The system calls a WH_CBT hook procedure before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; BEFORE removing a mouse or keyboard event from the system message queue; before setting the input focus; or before synchronizing with the system message queue. The value the hook procedure returns determines whether the system allows or prevents one of these operations.
Return Value
The value returned by the hook procedure determines whether the system allows or prevents one of these operations. For operations corresponding to the following CBT hook codes, the return value must be 0 to allow the operation, or 1 to prevent it:
HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND
For operations corresponding to the following CBT hook codes, the return value is ignored:
HCBT_CLICKSKIPPED
HCBT_KEYSKIPPED
HCBT_QS
Remarks
The hook procedure should NOT install a WH_JOURNALPLAYBACK_hook hook procedure except in the situations described in the preceding list of hook codes.
|
|
|
|
|
Pardon the big post...
I am using the code below to set my printer into Duplex mode, which has to be done via the driver as I sometimes want duplex printing in word, and sometimes I dont. Anyway, regardless of whether you think this can be done with System.Drawing.Printing or not, I want to limit this purely to "why do my API calls not work" as a worthwhile excercise in unmanaged code and interop...
Based on many articles I have seen on the web I came up with the class below, but it seems I am also suffering the same woes that every user who ever tried to switch duplex printing on, has suffered, and that it is hard to get it to work.
Why am I getting access denied as commented below?
Why do the docs say that OpenPrinter has to take a PRINTER_DEFAULTS byref, and when I pass it by ref, every thing breaks at runt time, like, I don't get a printer handle and OpenPrinter causes an Err.LastDllError of 5 (access denied).
I think you either know the answer to this one or not. I don't want speculcation and supposition, just hard tested solutions, coz the web is littered with suggestions that dont seem to work.
The fundamental problem seems to be that my code doesn't have the right security descriptior to use SetPrinter, even if I log on to my Windows 2003 server as an administrator.
Thanks guys, in advance for your patience and efforts!
''' TEST CODE FOR CLASS - put this in a form or module
Private Sub Test()
Dim lPrinter As New APIPrinter
Dim lName As String = lPrinter.DefaultPrinterName
lPrinter.Open(lName)
lPrinter.DuplexMode = APIPrinter.DuplexOption.LongEdge
lPrinter.Close()
End Sub
''' CODE FOR CLASS - put this in a spearate class VB file
Imports System.Runtime.InteropServices
Imports System.Text
Public Class APIPrinter
Implements IDisposable
#Region "WinApi"
#Region "Structures"
<StructLayout(LayoutKind.Sequential)> Public Structure PRINTER_DEFAULTS
<MarshalAs(UnmanagedType.LPStr)> Public pDatatype As String
Public pDevMode As IntPtr
Public DesiredAccess As Int32
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure PRINTER_INFO_2
<MarshalAs(UnmanagedType.LPStr)> Public pServerName As String
<MarshalAs(UnmanagedType.LPStr)> Public pPrinterName As String
<MarshalAs(UnmanagedType.LPStr)> Public pShareName As String
<MarshalAs(UnmanagedType.LPStr)> Public pPortName As String
<MarshalAs(UnmanagedType.LPStr)> Public pDriverName As String
<MarshalAs(UnmanagedType.LPStr)> Public pComment As String
<MarshalAs(UnmanagedType.LPStr)> Public pLocation As String
Public pDevMode As IntPtr
<MarshalAs(UnmanagedType.LPStr)> Public pSepFile As String
<MarshalAs(UnmanagedType.LPStr)> Public pPrintProcessor As String
<MarshalAs(UnmanagedType.LPStr)> Public pDatatype As String
<MarshalAs(UnmanagedType.LPStr)> Public pParameters As String
Public pSecurityDescriptor As Int32
Public Attributes As Int32
Public Priority As Int32
Public DefaultPriority As Int32
Public StartTime As Int32
Public UntilTime As Int32
Public Status As Int32
Public cJobs As Int32
Public AveragePPM As Int32
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure DEVMODE
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Public dmDeviceName As String
Public dmSpecVersion As Int32
Public dmDriverVersion As Int32
Public dmSize As Int32
Public dmDriverExtra As Int32
Public dmFields As Int32
Public dmOrientation As Int32
Public dmPaperSize As Int32
Public dmPaperLength As Int32
Public dmPaperWidth As Int32
Public dmScale As Int32
Public dmCopies As Int32
Public dmDefaultSource As Int32
Public dmPrintQuality As Int32
Public dmColor As Int32
Public dmDuplex As Int32
Public dmYResolution As Int32
Public dmTTOption As Int32
Public dmCollate As Int32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Public dmFormName As String
Public dmUnusedPadding As Int32
Public dmBitsPerPel As Int32
Public dmPelsWidth As Int32
Public dmPelsHeight As Int32
Public dmDisplayFlags As Int32
Public dmDisplayFrequency As Int32
End Structure
#End Region
#Region "Constants"
Public Const DM_DUPLEX = &H1000&
Public Const DM_IN_BUFFER = DM_MODIFY
Public Const DM_MODIFY = 8
Public Const DM_PROMPT = 4
Public Const DM_OUT_BUFFER = DM_COPY
Public Const DM_COPY = 2
Public Const PRINTER_ACCESS_ADMINISTER = &H4
Public Const PRINTER_ACCESS_USE = &H8
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)
#End Region
' HELP!!!
' This is the way the docs indicate that OpenPrinter should be declared. but if I do it this way
' then the call fails as described in the code below.
'Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, ByRef phPrinter As Int32, ByRef pDefault As PRINTER_DEFAULTS) As Int32
' HELP!!!
Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, ByRef phPrinter As Int32, ByVal pDefault As PRINTER_DEFAULTS) As Int32
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Int32) As Int32
Private Declare Function PrinterProperties Lib "winspool.drv" (ByVal hWND As Int32, ByVal hPrinter As Int32) As Int32
Private Declare Function DocumentProperties Lib "winspool.drv" Alias "DocumentPropertiesA" (ByVal hwnd As Int32, ByVal hPrinter As Int32, ByVal pDeviceNameg As String, ByVal pDevModeOutput As IntPtr, ByRef pDevModeInput As IntPtr, ByVal ByValfMode As Int32) As Int32
Private Declare Function GetPrinter Lib "winspool.drv" Alias "GetPrinterA" (ByVal hPrinter As Int32, ByVal Level As Int32, ByVal pPrinter As IntPtr, ByVal cbBuf As Int32, ByRef pcbNeeded As Int32) As Int32
Private Declare Function SetPrinter Lib "winspool.drv" Alias "SetPrinterA" (ByVal hPrinter As Int32, ByVal Level As Int32, ByVal pPrinter As IntPtr, ByVal Command As Int32) As Int32
Private Declare Function GetDefaultPrinter Lib "winspool.drv" Alias "GetDefaultPrinterA" (ByVal lName As String, ByRef lBuffLen As Int32) As Int32
#End Region
#Region "Properties and Enumerations"
Public Enum DuplexOption
None
LongEdge
ShortEdge
End Enum
Private mPrinterHandle As Int32
Private mDeviceMode As New DEVMODE
Private mName As String
Private mDuplexOption As DuplexOption
Private mDevModeSize As Int32
Private mMemBuffer As IntPtr
Public Shared ReadOnly Property DefaultPrinterName() As String
Get
Dim lName As String = Space(1024)
Dim lBuffLen As Int32 = Len(lName)
GetDefaultPrinter(lName, lBuffLen)
Return lName
End Get
End Property
Public Property Name() As String
Get
Return mName
End Get
Set(ByVal Value As String)
mName = Value
End Set
End Property
Public Property DuplexMode() As DuplexOption
Get
GetProperties()
Select Case mDeviceMode.dmDuplex
Case 1
Return DuplexOption.ShortEdge
Case 2
Return DuplexOption.LongEdge
Case Else
Return DuplexOption.None
End Select
End Get
Set(ByVal Value As DuplexOption)
mDuplexOption = Value
mDeviceMode.dmFields = DM_DUPLEX
Select Case mDuplexOption
Case DuplexOption.LongEdge
mDeviceMode.dmDuplex = 2
Case DuplexOption.ShortEdge
mDeviceMode.dmDuplex = 3
Case Else
mDeviceMode.dmDuplex = 1
End Select
SetProperties()
End Set
End Property
#End Region
Public Sub Open(ByVal pPrinterName As String)
Dim lDefaults As PRINTER_DEFAULTS
lDefaults.DesiredAccess = PRINTER_ALL_ACCESS
lDefaults.pDatatype = vbNullString
lDefaults.pDevMode = IntPtr.Zero
' HELP!!!
' If OpenPrinter uses ... ByRef pDefault As PRINTER_DEFAULTS then
' why does this call fail with Err.LastDllError = 5 (access denied)
' HELP!!!
Dim lRetCode As Integer = OpenPrinter(pPrinterName, mPrinterHandle, lDefaults)
If lRetCode = 0 Then
lRetCode = Err.LastDllError
End If
If Err.LastDllError = 5 Then
mPrinterHandle = 0
Else
If mPrinterHandle <> 0 Then
mDevModeSize = DocumentProperties(0, mPrinterHandle, pPrinterName, IntPtr.Zero, IntPtr.Zero, 0)
If mDevModeSize > 0 Then
mMemBuffer = Marshal.AllocCoTaskMem(mDevModeSize)
GetProperties()
Name = pPrinterName
End If
End If
End If
End Sub
Public Sub Close()
If mPrinterHandle > 0 Then
ClosePrinter(mPrinterHandle)
Marshal.FreeCoTaskMem(mMemBuffer)
End If
mPrinterHandle = 0
End Sub
Private Sub GetProperties()
If mPrinterHandle > 0 Then
Dim lRetCode As Integer = DocumentProperties(0, mPrinterHandle, mName, mMemBuffer, IntPtr.Zero, DM_OUT_BUFFER)
If lRetCode > 0 Then
mDeviceMode = Marshal.PtrToStructure(mMemBuffer, mDeviceMode.GetType)
End If
End If
End Sub
Public Sub SetProperties()
If mPrinterHandle > 0 Then
Dim lRetCode As Integer
mDeviceMode.dmOrientation = 2
mDeviceMode.dmDuplex = 2
Marshal.StructureToPtr(mDeviceMode, mMemBuffer, True)
lRetCode = DocumentProperties(0, mPrinterHandle, mName, mMemBuffer, mMemBuffer, DM_IN_BUFFER Or DM_OUT_BUFFER)
Dim lSharedStat As Boolean = SetSharedSettings()
lRetCode = DocumentProperties(0, mPrinterHandle, mName, mMemBuffer, mMemBuffer, DM_IN_BUFFER Or DM_OUT_BUFFER Or DM_PROMPT)
End If
End Sub
Private Function SetSharedSettings() As Boolean
Dim lBuffLen As Int32
Dim lRetCode As Int32 = GetPrinter(mPrinterHandle, 2, IntPtr.Zero, 0, lBuffLen)
If lBuffLen > 0 Then
Dim lBytesRead As Int32
Dim lBuff As IntPtr = Marshal.AllocCoTaskMem(lBuffLen)
lRetCode = GetPrinter(mPrinterHandle, 2, lBuff, lBuffLen, lBytesRead)
If lRetCode > 0 Then
Dim lInfo As PRINTER_INFO_2
lInfo = Marshal.PtrToStructure(lBuff, lInfo.GetType)
lInfo.pDevMode = mMemBuffer
lInfo.pSecurityDescriptor = 0
Marshal.StructureToPtr(lInfo, lBuff, True)
' HELP!!!
' This always fails with Err.LastDllError = 5 (access denied)
' This makes me think that there is someting wrong with the
' security descriptor.
' HELP!!!
lRetCode = SetPrinter(mPrinterHandle, 2, lBuff, 0)
If lRetCode <= 0 Then
lRetCode = Err.LastDllError
End If
Marshal.FreeCoTaskMem(lBuff)
Return True
End If
End If
Return False
End Function
Public Sub Dispose() Implements System.IDisposable.Dispose
If mPrinterHandle > 0 Then
Close()
End If
End Sub
End Class
Nursey
|
|
|
|
|
"I think you either know the answer to this one or not. I don't want speculcation and supposition"
hmmm... I'm not sure how to respond to that but, here goes.
I built your software using vs.net 2003, just as it is listed, on my win2k3 server, as Administrator, I tested it against my HP LaserJet 4100 DTN (with Duplex Mode), I had no permission errors, nor any errors of any kind, but your software also doesn't set the duplex mode for it either. It does however, bring up the printer settings dialog box where I can set it to duplex.
|
|
|
|
|
Thank you so much for going to all that effort. However, if y ou find these two lines of kludge...
mDeviceMode.dmOrientation = 2
mDeviceMode.dmDuplex = 2
You'll see that I do 'try' to set some properties, BUT, and this is where I have to thank you again. I didn't set the field mDeviceMode.dmFields, to tell the driver it needs to reset those two values, duplex and orientation. So you certainly helped me find a bug in my test case. I am not sure why I get the problem of Access Denied and you don't though. I wonder if its anything to do with the way we setup Win2k3 here. Win2k3 is my box and I guess that's subject to the SOE setup used at work. Perhaps I can do a fix and send you some more code to test, would that be ok.
Again, thanks a bunch!
Nursey
|
|
|
|
|
Yes I will be Happy to test it again, also I Do happen to know or at least have a good probable "Idea" of why yours is failing with error 5.
1) OpenPrinter will not connect directly to a network print queue device or driver.
2) If your's is set that way and I suspect it is, (and it does fail with error 5, on mine here also, from a networked windows XP machine.) you need to create a local device that points to the network printer, then create a local print queue by performing the following steps:
From a command prompt, type
NET USE LPT2: \\<printer server="">\<printer> /persistent:yes
to map the local LPT device to the network printer.
Add a local printer in the usual way (go to Start, Settings, Printers, and click Add Printer).
Specify a local device you made above (LPT2), and configure the new printer.
You Must have a local printer device for it to work at all.
3) It will not work at all on any LPT Device above LPT2.(At Least not on my equipment.)
and I go up to LPT4 so it must have a problem with High Irq's also.
Glad to help.
|
|
|
|
|
This is why I put things like "don't answer unless you know the answer", because every so often then it reduces the clutter and gives a guru a chance to get through! 8-)
I will try and map the local port and give it another spin.
I would never have found this information other than by your gratious efforts.
Many thanks.
Nursey
|
|
|
|
|
I captured LPT2, having added a local printer using the same driver, but I get the same result...return code 5 when calling SetPrinter.
You said >>OpenPrinter will not connect directly to a network print queue device or driver
But everything works really well in terms of reading things about the printer, i.e. its name, location, capabilities etc.
Any other thoughts?
Could there be some kind of policy enforced by our network people that could affect this. Sorry I don't know too much about domains and server configs. My machine is a Win2K3 box, but it log into a corporate domain. I wotk for the ministry of justice in Perth, Australia, so I reckon you can guess that things are pretty well tightened up in terms of security policies and the like.
It doens't change anything if I login into my box as an administrator. I normally log in to the domain and develop.
Thanks again.
Nursey
|
|
|
|
|
Yes, I'm sure they would be Inforcing a group policy on the printers, and when you log into the domain the policy automaticly set's your computer also.
Before I go on...
Where is the physical printer at, your place or at work?
|
|
|
|
|
The printer is at my workplace, I just add printer, it's shared from an old server, I looked it up and added it. I can obviously print ok. I can set duplex printing from Word, and print in the normal way. I just have to be able to set duplex on and off from code for some special cases.
BTW, would you rather email me to save time on here? chris.nurse@justice.wa.gov.au
Thx.
Nursey
|
|
|
|
|
I can give your email a try, but I am on the other side of the world from you in the US, so It may be faster to us CP, but I'll give it a try and see.
|
|
|
|
|
Can I just ask, did you actually step the code and look at all the dll last error codes? If so are you saying you didn't get any occurences of error 5 anywhere?
Ta!
Nursey
|
|
|
|
|
Yes I stepped through the code, And No I got No error 5's except in the situation of the XP machine on the network in previous message.
Also,
The last meassage was supposed to read:
From a command prompt, type
NET USE LPT2: \\<printer server>\<printer> /persistent:yes
to map the local LPT device to the network printer.
|
|
|
|
|
G'day All,
My checkbox unchecks itself when I programatically change the data in the underlying record from within the CheckedChanged event
Private Sub chbActive_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chbActive.CheckedChanged
If chbActive.Checked Then
'Set name to 'Bert'
Dim Pos As Integer = Me.BindingContext(Me.Ds_Students, "Students").Position
Dim dv As DataView
Dim strExp = "StudentCode = "
Dim sc As String = CType(Me.Ds_Students.Students(Pos).StudentCode, String)
strExp += sc
dv = Me.Ds_Students.Students.DefaultView
dv.RowFilter = strExp
dv(0)("Name") = "Bert" 'This line causes the problem
End If
End Sub
When clicking on the checkbox chbActive the checkbox initially displays a check, but after setting name to Bert the checkbox unchecks itself.
Can anyone please explain why?
Please send replies to craigandrow@ozemail.com.au
Regards,
Craig
|
|
|
|
|
Check if you have a code in DV_Change or any other events that occure when dataview changes, that sets the value of the checkbox.
(check it by running this sub, line by line using F8 key, then you could correct this problem)
|
|
|
|
|
How do you superimpose a datepicker into a datagrid.
|
|
|
|
|
This shows how to add a datetimepicker to a datagrid.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformsdatagridcolumnstyleclasstopic.asp
|
|
|
|
|
hello there -
i have a bitmap image, saved in an byte array to transfer this to the network.
up to now, i realised this by the remoting technology of .Net. i just called a
function of my remote client with a byte array parameter.
if i do this with just one client - everything works fine. i got an image transfer rate
of about half a second (i want to transfer the screenshot of my desktop and try
to get a smooth motion).
but my application will run with about 10 to 20 clients and therefore i will have
a transferrate of 5 to 6 second per image, what is definetly to slow. at the
moment i just run through an array of my clients, as you can see in the following
code:
Public Sub _captureScreen()
Dim i As Integer
Dim user As IClient
Dim screenTime As DateTime
Dim duration As TimeSpan
Do While keepRunning
screenTime = DateTime.Now
Dim getScreenShot As Interfaces.ScreenShot
Dim ic As Byte()
Try
Dim screen As Image
screen = getScreenShot.GetDesktopImage
'Ein MemoryStream wird deklariert
Dim ms As New System.IO.MemoryStream()
'Das Image wird Byteweise in den MemoryStream gespeichert
screen.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
'Das sich im Buffer des MemoryStream befindliche ByteArray wird im ic
gespeichert
ic = ms.GetBuffer()
'Der MemoryStream wird freigegeben
ms.Flush()
ms.Close()
ms = Nothing
screen.Dispose()
screen = Nothing
Catch e As Exception
MessageBox.Show(e.ToString)
End Try
For i = 0 To server._clients.Count - 1
user = server._clients(i)
Try
SyncLock user
user._giveServerScreenShot(ic, server.guid)
End SyncLock
Catch e As Exception
server._reOrgArray()
End Try
Next
ic = Nothing
getScreenShot = Nothing
duration = DateTime.Now.Subtract(screenTime)
server._schoolMain.screenTime.Text = duration.ToString
Loop
End Sub
so, has anyone any idea how i can optimize my image transfer rate?
thanks for all help.
tom
|
|
|
|
|
I knew you were going to run into this problem. The solution is to not transfer the entire screen image. Only transfer the parts that change. But to do this, you'll have to come up with two schemes. One, to "bounding box" the parts of the image that changes, keeping in mind that you can have multiple areas of the screen that change, and... Two, a protocol that transfers just the parts that change and can be reassembled on the server side.
You really should have done some homework on the concept first. Search the web for "VNC". You'll find a bunch of remote control software, including screen shot transfer, with most of it being publicly available with source code. Try http://www.realvnc.com/[^] or http://www.tightvnc.com/[^] for a couple of examples.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Dave - you really are my man! you always answer my questions and i appreciate that very much. thanks for this! i hope i can do something for you, when the time comes and you need help.
well, i look about thread pooling and i think this could be a good solution. running maximal 40 threads at a time in a threadpool is acceptable i think.
problem is: i didn't really get the clou about how the pooling is working.
|
|
|
|
|
well - after long try out, i am now at the point to send my graphic as udp-broadcast. problem is: the graphic is to large for one udp packet. i want to split the graphic in for sections, send these section and build them together on the other side. but i dont know how to cut bitmap and then rebuild the pieces to a whole again. do you have an idea how this can work? i guess you have. you always have.
|
|
|
|
|
we have a design project wherein we have to make a visual basic program that is interfaced with the parallel port. what is the requirements or needed files for us to interface with the parallel port of a computer? what are the code for every pin on the parallel port.
i hope some one can help me with this. thanks a lot!
|
|
|
|
|
|
thanks a lot sir dave! but i need the codes for the visual basic 6 or . net (but preferrably vb 6) and using the windows application. i hope that you could help me again. thanks again!
|
|
|
|
|