SubClass Form to recieve Clipboard Changes
Author |
Message |
Cr #1 / 6
|
 SubClass Form to recieve Clipboard Changes
Greetings, I am a newbie who made a little program that whenever I get new text into my clipboard it pastes that text into a listbox. I did this by checking the clipboard by a timer set to 1 second. I was told that there was a better way to do this than the timer. I was told about subclassing the form to recieve a message that the clipboard has changed. For the last several days I have been reading about subclassing, and SendMessage, etc. and am now more confused than ever:). Not sure of which functions to use or how to access the cliboard data once I am informed of a change. Does anyone have any leads about how to do this? What api functions I might need? ANd basically a description in simple english of how it is done so that I might read the right references to figure it out. Maybe a good site with a good description of how to subclass. Any takers? Mark
|
Tue, 04 Jun 2002 03:00:00 GMT |
|
 |
Jason Bouzan #2 / 6
|
 SubClass Form to recieve Clipboard Changes
Subclassing is a very touchy subject and it is not a good idea for somebody new to programming to jump right into such a topic without first becoming familiar with the language. For example, when subclassing, you cannot use the Stop button or the End statement and it is very difficult to debug the application. If there is a bug in your application, your program will probably crash taking the IDE with it. Sticking with the one second timer really isn't such a bad idea, unless you are working with large amounts of text. But I will still give you a pointer to checking the clipboard. Add the following code to a module: Public Declare Function SetClipboardViewer Lib "user32.dll" (ByVal hWnd As Long) As Long Public Declare Function ChangeClipboardChain Lib "user32.dll" (ByVal hWndRemove As Long, ByVal hWndNext As Long) As Long Public Declare Function SendMessageA Lib "user32.dll" (ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Declare Function SetWindowLongA Lib "user32.dll" (ByVal hWnd As Long, ByVal nIndex As Integer, ByVal dwNewValue As Long) As Long Public Declare Function CallWindowProcA Lib "user32.dll" (ByVal lpfnWndProc As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Const WM_CHANGECBCHAIN = &H30D Public Const WM_DRAWCLIPBOARD = &H308 Public Const GWL_WNDPROC = -4 Public hWndNext As Long Public lpfnWndProc As Long Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Select Case uMsg Case WM_DRAWCLIPBOARD If Clipboard.GetFormat(vbCFText) Then frmMain.lstList.AddItem Clipboard.GetText(vbCFText) End If SendMessageA hWndNext, uMsg, wParam, lParam WndProc = 0 Exit Function Case WM_CHANGECBCHAIN If wParam = hWndNext Then lParam = hWndNext End If SendMessageA hWndNext, uMsg, wParam, lParam WndProc = 0 Exit Function Case Else WndProc = CallWindowProcA(lpfnWndProc, hWnd, uMsg, wParam, lParam) Exit Function End Select End Function And add the following code to a form named frmMain with a list box control called lstList on it: Private Sub Form_Load() lpfnWndProc = SetWindowLongA(hWnd, GWL_WNDPROC, AddressOf WndProc) hWndNext = SetClipboardViewer(hWnd) End Sub Now, subclassing is when you handle the work that VB does behind the scenes. When Windows wants to let your program know that an event has occured, it sends your window a message. This message is sent to the window procedure of your window, which is basically a function. Normally, VisualBasic provides a window procedure and when it is sent a message, like WM_SIZE, it causes the form to trigger a Form_Resize event. But sometimes you need to listen for messages that VisualBasic does not automatically send to the form. For example, the WM_MOVE message is sent to the window procedure when the window is being moved, but you will notice that there is no VB event triggered for this message, so if you want to check when the form is being moved, you have to subclass the form and listen for a WM_MOVE message. In the above example, the window listens for two different messages, WM_CHANGECBCHAIN, and WM_DRAWCLIPBOARD these messages aren't usually sent to the window unless you have set it up as a clipboard listener, as is done in the second line of the Form_Load event. The first line of this procedure is to actually do the subclassing of the form. It sets the window procedure to the function WndProc and stores the last function in a variable called lpfnWndProc. The function listens for certain messages, such as WM_CHANGECBCHAIN, and takes appropriate action. If a message is sent to it that it does not want any special action taken for, such as WM_SIZE, the default action should be taken. This is done by sending the message to the old window procedure, which has been stored in the variable lpfnWndProc. The WM_DRAWCLIPBOARD message is sent to the window when the clipboard contents have changed, so the new text is added to the list box. The WM_CHANGECBCHAIN also has to be processed because your window has been registered in a list of windows that watch the clipboard. You have to pass the message to the next window in the chain when the clipboard is updated, so you have to process the WM_CHANGECBCHAIN when a window is removed from the chain. If the window is the one after yours, you have to pass the message to a different window because the one you normally send it to is gone. You can pick through this code and see what you make of it, but this should, by no means, be used as a complete guide to subclassing. This might, perhaps give you a better understanding of subclassing, or it may just confuse you even more. -- Hope this helps, Jason Bouzane Quote:
> Greetings, > I am a newbie who made a little program that whenever I get new text > into my clipboard it pastes that text into a listbox. I did this by > checking the clipboard by a timer set to 1 second. I was told that > there was a better way to do this than the timer. I was told about > subclassing the form to recieve a message that the clipboard has > changed. For the last several days I have been reading about > subclassing, and SendMessage, etc. and am now more confused than > ever:). Not sure of which functions to use or how to access the > cliboard data once I am informed of a change. Does anyone have any > leads about how to do this? What api functions I might need? ANd > basically a description in simple english of how it is done so that I > might read the right references to figure it out. Maybe a good site > with a good description of how to subclass. Any takers? > Mark
|
Tue, 04 Jun 2002 03:00:00 GMT |
|
 |
Jason Bouza #3 / 6
|
 SubClass Form to recieve Clipboard Changes
This is a multi-part message in MIME format. ------=_NextPart_000_00D7_01BF48DF.9C2D8900 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Subclassing is a very touchy subject and it is not a good idea for = somebody new to programming to jump right into such a topic without = first becoming familiar with the language. For example, when = subclassing, you cannot use the Stop button or the En d statement and it = is very difficult to debug the application. If there is a bug in your = application, your program will probably crash taking the IDE with it. = Sticking with the one second timer really isn't such a bad idea, unless = you are working with large amounts of text. But I will still give you a = pointer to checking the clipboard. Add the following code to a module: Public Declare Function SetClipboardViewer Lib "user32.dll" (ByVal hWnd = As Long) As Long Public Declare Function ChangeClipboardChain Lib "user32.dll" (ByVal = hWndRemove As Long, ByVal hWndNext As Long) As Long Public Declare Function SendMessageA Lib "user32.dll" (ByVal hWnd As = Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam A s Long) As = Long Public Declare Function SetWindowLongA Lib "user32.dll" (ByVal hWnd As = Long, ByVal nIndex As Integer, ByVal dwNewValue As Long) As Long Public Declare Function CallWindowProcA Lib "user32.dll" (ByVal = lpfnWndProc As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal = wParam As Long, ByVal lParam As Long) As Long Public Const WM_CHANGECBCHAIN =3D &H30D Public Const WM_DRAWCLIPBOARD =3D &H308 Public Const GWL_WNDPROC =3D -4 Public hWndNext As Long Public lpfnWndProc As Long Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal = wParam As Long, ByVal lParam As Long) As Long Select Case uMsg Case WM_DRAWCLIPBOARD If Clipboard.GetFormat(vbCFText) Then frmMain.lstList.AddItem Clipboard.GetText(vbCFText) End If SendMessageA hWndNext, uMsg, wParam, lParam WndProc =3D 0 Exit Function Case WM_CHANGECBCHAIN If wParam =3D hWndNext Then=20 lParam =3D hWndNext End If SendMessageA hWndNext, uMsg, wParam, lParam WndProc =3D 0 Exit Function Case Else WndProc =3D CallWindowProcA(lpfnWndProc, hWnd, uMsg, wParam, lParam) Exit Function End Select End Function And add the following code to a form named frmMain with a list box = control called lstList on it: Private Sub Form_Load() lpfnWndProc =3D SetWindowLongA(hWnd, GWL_WNDPROC, AddressOf WndProc) hWndNext =3D SetClipboardViewer(hWnd) End Sub Now, subclassing is when you handle the work that VB does behind the = scenes. When Windows wants to let your program know that an event has = occured, it sends your window a message. This message is sent to the = window procedure of your window, which is basically a function. = Normally, VisualBasic provides a window procedure and when it is sent a = message, like WM_SIZE, it causes the form to trigger a Form_Resize = event. But sometimes you need to listen for messages that VisualBasic = does not automa tically send to the form. For example, the WM_MOVE = message is sent to the window procedure when the window is being moved, = but you will notice that there is no VB event triggered for this = message, so if you want to check when the form is being moved , you have = to subclass the form and listen for a WM_MOVE message. In the above = example, the window listens for two different messages, = WM_CHANGECBCHAIN, and WM_DRAWCLIPBOARD these messages aren't usually = sent to the window unless you have set it u p as a clipboard listener, as = is done in the second line of the Form_Load event. The first line of = this procedure is to actually do the subclassing of the form. It sets = the window procedure to the function WndProc and stores the last = function in a variable called lpfnWndProc. The function listens for = certain messages, such as WM_CHANGECBCHAIN, and takes appropriate = action. If a message is sent to it that it does not want any special = action taken for, such as WM_SIZE, the default action shoul d be taken. = This is done by sending the message to the old window procedure, which = has been stored in the variable lpfnWndProc. The WM_DRAWCLIPBOARD = message is sent to the window when the clipboard contents have changed, = so the new text is added t o the list box. The WM_CHANGECBCHAIN also has = to be processed because your window has been registered in a list of = windows that watch the clipboard. You have to pass the message to the = next window in the chain when the clipboard is updated, so you h ave to = process the WM_CHANGECBCHAIN when a window is removed from the chain. If = the window is the one after yours, you have to pass the message to a = different window because the one you normally send it to is gone. You = can pick through this code a nd see what you make of it, but this should, = by no means, be used as a complete guide to subclassing. This might, = perhaps give you a better understanding of subclassing, or it may just = confuse you even more. --=20 Hope this helps, Jason Bouzane
Quote: > Greetings, > I am a newbie who made a little program that whenever I get new text > into my clipboard it pastes that text into a listbox. I did this by > checking the clipboard by a timer set to 1 second. I was told that > there was a better way to do this than the timer. I was told about > subclassing the form to recieve a message that the clipboard has > changed. For the last several days I have been reading about > subclassing, and SendMessage, etc. and am now more confused than > ever:). Not sure of which functions to use or how to access the > cliboard data once I am informed of a change. Does anyone have any > leads about how to do this? What api functions I might need? ANd > basically a description in simple english of how it is done so that I > might read the right references to figure it out. Maybe a good site > with a good description of how to subclass. Any takers? > Mark >=20
------=_NextPart_000_00D7_01BF48DF.9C2D8900 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD> <META http-equiv=3DContent-Type content=3D"text/html; = charset=3Diso-8859-1"> <META content=3D"MSHTML 5.50.3825.1300" name=3DGENERATOR> <STYLE></STYLE> </HEAD> <BODY> <DIV><FONT face=3DArial size=3D2>Subclassing is a very touchy subject = and it is not=20 a good idea for somebody new to programming to jump right into such a = topic=20 without first becoming familiar with the language. For example, when=20 subclassing, you cannot use the Stop button or the End statement and it = is very=20 difficult to debug the application. If there is a bug in your = application, your=20 program will probably crash taking the IDE with it. Sticking with the = one second=20 timer really isn't such a bad idea, unless you are working with large = amounts of=20 text. But I will still give you a pointer to checking the clipboard. Add = the=20 following code to a module:</FONT></DIV><PRE>Public Declare Function = SetClipboardViewer Lib "user32.dll" (ByVal hWnd As Long) As Long Public Declare Function ChangeClipboardChain Lib "user32.dll" (ByVal = hWndRemove As Long, ByVal hWndNext As Long) As L ong Public Declare Function SendMessageA Lib "user32.dll" (ByVal hWnd As = Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As = Long Public Declare Function SetWindowLongA Lib "user32.dll" (ByVal hWnd As = Long, ByVal nIndex As Integer, ByVal dwNewValue As Long) As Long Public Declare Function CallWindowProcA Lib "user32.dll" (ByVal = lpfnWndProc As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal = wParam As Long, ByVal lParam As Long) As Long Public Const WM_CHANGECBCHAIN =3D &H30D Public Const WM_DRAWCLIPBOARD =3D &H308 Public Const GWL_WNDPROC =3D -4 Public hWndNext As Long Public lpfnWndProc As Long Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal = wParam As Long, ByVal lParam As Long) As Long Select Case uMsg Case WM_DRAWCLIPBOARD If Clipboard.GetFormat(vbCFText) Then frmMain.lstList.AddItem Clipboard.GetText(vbCFText) End If SendMessageA hWndNext, uMsg, wParam, lParam WndProc =3D 0 Exit Function Case WM_CHANGECBCHAIN If wParam =3D hWndNext Then=20 lParam =3D hWndNext End If SendMessageA hWndNext, uMsg, wParam, lParam WndProc =3D 0 Exit Function Case Else WndProc =3D CallWindowProcA(lpfnWndProc, hWnd, uMsg, wParam, lParam) Exit Function End Select End Function</PRE> <DIV><FONT face=3DArial size=3D2>And add the following code to a form = named frmMain=20 with a list box control called lstList on it:</FONT></DIV> <DIV><FONT face=3DArial size=3D2></FONT> </DIV><PRE>Private Sub = Form_Load() lpfnWndProc =3D SetWindowLongA(hWnd, GWL_WNDPROC, AddressOf WndProc) hWndNext =3D SetClipboardViewer(hWnd) End Sub</PRE> <DIV><FONT face=3DArial size=3D2>Now, subclassing is when you handle the = work that=20 VB does behind the scenes. When Windows wants to let
... read more »
|
Tue, 04 Jun 2002 03:00:00 GMT |
|
 |
Cr #4 / 6
|
 SubClass Form to recieve Clipboard Changes
Greetings, I am a newbie who made a little program that whenever I get new text into my clipboard it pastes that text into a listbox. I did this by checking the clipboard by a timer set to 1 second. I was told that there was a better way to do this than the timer. I was told about subclassing the form to recieve a message that the clipboard has changed. For the last several days I have been reading about subclassing, and SendMessage, etc. and am now more confused than ever:). Not sure of which functions to use or how to access the cliboard data once I am informed of a change. Does anyone have any leads about how to do this? What api functions I might need? ANd basically a description in simple english of how it is done so that I might read the right reference s to figure it out. Maybe a good site with a good description of how to subclass. Any takers? Mark
|
Tue, 04 Jun 2002 03:00:00 GMT |
|
 |
Cr #5 / 6
|
 SubClass Form to recieve Clipboard Changes
Jason, Thanks for the excellent explanation. It definatly helped in explaining what was going on in my program. Thanks for taking the time to do that. BTW, in your code, and others I see in various places, you used 3D in your code. WHat does 3D mean? Thanks again for the great help. Mark On Fri, 17 Dec 1999 22:39:42 -0330 Quote: >This is a multi-part message in MIME format. >------=_NextPart_000_00D7_01BF48DF.9C2D8900 >Content-Type: text/plain; > charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable >Subclassing is a very touchy subject and it is not a good idea for = >somebody new to programming to jump right into such a topic without = >first becoming familiar with the language. For example, when = >subclassing, you cannot use the Stop button or the End statement and it = >is very difficult to debug the application. If there is a bug in your = >application, your program will probably crash taking the IDE with it. = >Sticking with the one second timer really isn't such a bad idea, unless = >you are working with large amounts of text. But I will still give you a = >pointer to checking the clipboard. Add the following code to a module: >Public Declare Function SetClipboardViewer Lib "user32.dll" (ByVal hWnd = >As Long) As Long >Public Declare Function ChangeClipboardChain Lib "user32.dll" (ByVal = >hWndRemove As Long, ByVal hWndNext As Long) As Long >Public Declare Function SendMessageA Lib "user32.dll" (ByVal hWnd As = >Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As = >Long >Public Declare Function SetWindowLongA Lib "user32.dll" (ByVal hWnd As = >Long, ByVal nIndex As Integer, ByVal dwNewValue As Long) As Long >Public Declare Function CallWindowProcA Lib "user32.dll" (ByVal = >lpfnWndProc As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal = >wParam As Long, ByVal lParam As Long) As Long >Public Const WM_CHANGECBCHAIN =3D &H30D >Public Const WM_DRAWCLIPBOARD =3D &H308 >Public Const GWL_WNDPROC =3D -4 >Public hWndNext As Long >Public lpfnWndProc As Long >Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal = >wParam As Long, ByVal lParam As Long) As Long > Select Case uMsg > Case WM_DRAWCLIPBOARD > If Clipboard.GetFormat(vbCFText) Then > frmMain.lstList.AddItem Clipboard.GetText(vbCFText) > End If > SendMessageA hWndNext, uMsg, wParam, lParam > WndProc =3D 0 > Exit Function > Case WM_CHANGECBCHAIN > If wParam =3D hWndNext Then=20 > lParam =3D hWndNext > End If > SendMessageA hWndNext, uMsg, wParam, lParam > WndProc =3D 0 > Exit Function > Case Else > WndProc =3D CallWindowProcA(lpfnWndProc, hWnd, uMsg, wParam, lParam) > Exit Function > End Select >End Function >And add the following code to a form named frmMain with a list box = >control called lstList on it: >Private Sub Form_Load() > lpfnWndProc =3D SetWindowLongA(hWnd, GWL_WNDPROC, AddressOf WndProc) > hWndNext =3D SetClipboardViewer(hWnd) >End Sub >Now, subclassing is when you handle the work that VB does behind the = >scenes. When Windows wants to let your program know that an event has = >occured, it sends your window a message. This message is sent to the = >window procedure of your window, which is basically a function. = >Normally, VisualBasic provides a window procedure and when it is sent a = >message, like WM_SIZE, it causes the form to trigger a Form_Resize = >event. But sometimes you need to listen for messages that VisualBasic = >does not automatically send to the form. For example, the WM_MOVE = >message is sent to the window procedure when the window is being moved, = >but you will notice that there is no VB event triggered for this = >message, so if you want to check when the form is being moved, you have = >to subclass the form and listen for a WM_MOVE message. In the above = >example, the window listens for two different messages, = >WM_CHANGECBCHAIN, and WM_DRAWCLIPBOARD these messages aren't usually = >sent to the window unless you have set it up as a clipboard listener, as = >is done in the second line of the Form_Load event. The first line of = >this procedure is to actually do the subclassing of the form. It sets = >the window procedure to the function WndProc and stores the last = >function in a variable called lpfnWndProc. The function listens for = >certain messages, such as WM_CHANGECBCHAIN, and takes appropriate = >action. If a message is sent to it that it does not want any special = >action taken for, such as WM_SIZE, the default action should be taken. = >This is done by sending the message to the old window procedure, which = >has been stored in the variable lpfnWndProc. The WM_DRAWCLIPBOARD = >message is sent to the window when the clipboard contents have changed, = >so the new text is added to the list box. The WM_CHANGECBCHAIN also has = >to be processed because your window has been registered in a list of = >windows that watch the clipboard. You have to pass the message to the = >next window in the chain when the clipboard is updated, so you have to = >process the WM_CHANGECBCHAIN when a window is removed from the chain. If = >the window is the one after yours, you have to pass the message to a = >different window because the one you normally send it to is gone. You = >can pick through this code and see what you make of it, but this should, = >by no means, be used as a complete guide to subclassing. This might, = >perhaps give you a better understanding of subclassing, or it may just = >confuse you even more. >--=20 >Hope this helps, >Jason Bouzane
>> Greetings, >> I am a newbie who made a little program that whenever I get new text >> into my clipboard it pastes that text into a listbox. I did this by >> checking the clipboard by a timer set to 1 second. I was told that >> there was a better way to do this than the timer. I was told about >> subclassing the form to recieve a message that the clipboard has >> changed. For the last several days I have been reading about >> subclassing, and SendMessage, etc. and am now more confused than >> ever:). Not sure of which functions to use or how to access the >> cliboard data once I am informed of a change. Does anyone have any >> leads about how to do this? What api functions I might need? ANd >> basically a description in simple english of how it is done so that I >> might read the right references to figure it out. Maybe a good site >> with a good description of how to subclass. Any takers? >> Mark >>=20 >------=_NextPart_000_00D7_01BF48DF.9C2D8900 >Content-Type: text/html; > charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable ><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ><HTML><HEAD> ><META http-equiv=3DContent-Type content=3D"text/html; = >charset=3Diso-8859-1"> ><META content=3D"MSHTML 5.50.3825.1300" name=3DGENERATOR> ><STYLE></STYLE> ></HEAD> ><BODY> ><DIV><FONT face=3DArial size=3D2>Subclassing is a very touchy subject = >and it is not=20 >a good idea for somebody new to programming to jump right into such a = >topic=20 >without first becoming familiar with the language. For example, when=20 >subclassing, you cannot use the Stop button or the End statement and it = >is very=20 >difficult to debug the application. If there is a bug in your = >application, your=20 >program will probably crash taking the IDE with it. Sticking with the = >one second=20 >timer really isn't such a bad idea, unless you are working with large = >amounts of=20 >text. But I will still give you a pointer to checking the clipboard. Add = >the=20 >following code to a module:</FONT></DIV><PRE>Public Declare Function = >SetClipboardViewer Lib "user32.dll" (ByVal hWnd As Long) As Long >Public Declare Function ChangeClipboardChain Lib "user32.dll" (ByVal = >hWndRemove As Long, ByVal hWndNext As Long) As Long >Public Declare Function SendMessageA Lib "user32.dll" (ByVal hWnd As = >Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As = >Long >Public Declare Function SetWindowLongA Lib "user32.dll" (ByVal hWnd As = >Long, ByVal nIndex As Integer, ByVal dwNewValue As Long) As Long >Public Declare Function CallWindowProcA Lib "user32.dll" (ByVal = >lpfnWndProc As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal = >wParam As Long, ByVal lParam As Long) As Long >Public Const WM_CHANGECBCHAIN =3D &H30D >Public Const WM_DRAWCLIPBOARD =3D &H308 >Public Const GWL_WNDPROC =3D -4 >Public hWndNext As Long >Public lpfnWndProc As Long >Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal = >wParam As Long, ByVal lParam As Long) As Long > Select Case uMsg > Case WM_DRAWCLIPBOARD > If Clipboard.GetFormat(vbCFText) Then > frmMain.lstList.AddItem Clipboard.GetText(vbCFText) > End If > SendMessageA hWndNext, uMsg, wParam, lParam > WndProc =3D 0 > Exit Function > Case WM_CHANGECBCHAIN > If wParam =3D hWndNext Then=20 > lParam =3D hWndNext > End If > SendMessageA hWndNext, uMsg, wParam, lParam > WndProc =3D 0 > Exit Function > Case Else > WndProc =3D CallWindowProcA(lpfnWndProc, hWnd, uMsg, wParam, lParam) > Exit Function > End Select >End Function</PRE> ><DIV><FONT face=3DArial size=3D2>And add the following code to a form = >named frmMain=20 >with a list box control called lstList on it:</FONT></DIV> ><DIV><FONT face=3DArial size=3D2></FONT>?</DIV><PRE>Private Sub = >Form_Load() > lpfnWndProc =3D SetWindowLongA(hWnd, GWL_WNDPROC, AddressOf WndProc) > hWndNext =3D SetClipboardViewer(hWnd) >End Sub</PRE> ><DIV><FONT face=3DArial size=3D2>Now, subclassing is when you handle the = >work that=20 >VB does behind the scenes. When Windows wants to let your program know = >that an=20 >event has occured, it sends your window a message. This message is sent = >to the=20 >window procedure of your window, which is basically a function. = >Normally,=20 >VisualBasic provides a window procedure and when it is
... read more »
|
Wed, 05 Jun 2002 03:00:00 GMT |
|
 |
Cr #6 / 6
|
 SubClass Form to recieve Clipboard Changes
Jason, Thanks for the excellent explanation. It definatly helped in explaining what was going on in my program. Thanks for taking the time to do that. BTW, in your code, and others I see in various places, you used 3D in your code. WHat does 3D mean? Thanks again for the great help. Mark On Fri, 17 Dec 1999 22:39:42 -0330 Quote: >This is a multi-part message in MIME format. >------=_NextPart_000_00D7_01BF48DF.9C2D8900 >Content-Type: text/plain; > charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable >Subclassing is a very touchy subject and it is not a good idea for = >somebody new to programming to jump right into such a topic without = >first becoming familiar with the language. For example, when = >subclassing, you cannot use the Stop button or the End statement and it = >is very difficult to debug the application. If there is a bug in your = >application, your program will probably crash taking the IDE with it. = >Sticking with the one second timer really isn't such a bad idea, unless = >you are working with large amounts of text. But I will still give you a = >pointer to checking the clipboard. Add the following code to a module: >Public Declare Function SetClipboardViewer Lib "user32.dll" (ByVal hWnd = >As Long) As Long >Public Declare Function ChangeClipboardChain Lib "user32.dll" (ByVal = >hWndRemove As Long, ByVal hWndNext As Long) As Long >Public Declare Function SendMessageA Lib "user32.dll" (ByVal hWnd As = >Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As = >Long >Public Declare Function SetWindowLongA Lib "user32.dll" (ByVal hWnd As = >Long, ByVal nIndex As Integer, ByVal dwNewValue As Long) As Long >Public Declare Function CallWindowProcA Lib "user32.dll" (ByVal = >lpfnWndProc As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal = >wParam As Long, ByVal lParam As Long) As Long >Public Const WM_CHANGECBCHAIN =3D &H30D >Public Const WM_DRAWCLIPBOARD =3D &H308 >Public Const GWL_WNDPROC =3D -4 >Public hWndNext As Long >Public lpfnWndProc As Long >Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal = >wParam As Long, ByVal lParam As Long) As Long > Select Case uMsg > Case WM_DRAWCLIPBOARD > If Clipboard.GetFormat(vbCFText) Then > frmMain.lstList.AddItem
Clipboard.GetText(vbCFText) Quote: > End If > SendMessageA hWndNext, uMsg, wParam, lParam > WndProc =3D 0 > Exit Function > Case WM_CHANGECBCHAIN > If wParam =3D hWndNext Then=20 > lParam =3D hWndNext > End If > SendMessageA hWndNext, uMsg, wParam, lParam > WndProc =3D 0 > Exit Function > Case Else > WndProc =3D CallWindowProcA(lpfnWndProc, hWnd, uMsg, wParam, lParam) > Exit Function > End Select >End Function >And add the following code to a form named frmMain with a list box = >control called lstList on it: >Private Sub Form_Load() > lpfnWndProc =3D SetWindowLongA(hWnd, GWL_WNDPROC, AddressOf WndProc) > hWndNext =3D SetClipboardViewer(hWnd) >End Sub >Now, subclassing is when you handle the work that VB does behind the = >scenes. When Windows wants to let your program know that an event has = >occured, it sends your window a message. This message is sent to the = >window procedure of your window, which is basically a function. = >Normally, VisualBasic provides a window procedure and when it is sent a = >message, like WM_SIZE, it causes the form to trigger a Form_Resize = >event. But sometimes you need to listen for messages that VisualBasic = >does not automatically send to the form. For example, the WM_MOVE = >message is sent to the window procedure when the window is being moved, = >but you will notice that there is no VB event triggered for this = >message, so if you want to check when the form is being moved, you have = >to subclass the form and listen for a WM_MOVE message. In the above = >example, the window listens for two different messages, = >WM_CHANGECBCHAIN, and WM_DRAWCLIPBOARD these messages aren't usually = >sent to the window unless you have set it up as a clipboard listener, as = >is done in the second line of the Form_Load event. The first line of = >this procedure is to actually do the subclassing of the form. It sets = >the window procedure to the function WndProc and stores the last = >function in a variable called lpfnWndProc. The function listens for = >certain messages, such as WM_CHANGECBCHAIN, and takes appropriate = >action. If a message is sent to it that it does not want any special = >action taken for, such as WM_SIZE, the default action should be taken. = >This is done by sending the message to the old window procedure, which = >has been stored in the variable lpfnWndProc. The WM_DRAWCLIPBOARD = >message is sent to the window when the clipboard contents have changed, = >so the new text is added to the list box. The WM_CHANGECBCHAIN also has = >to be processed because your window has been registered in a list of = >windows that watch the clipboard. You have to pass the message to the = >next window in the chain when the clipboard is updated, so you have to = >process the WM_CHANGECBCHAIN when a window is removed from the chain. If = >the window is the one after yours, you have to pass the message to a = >different window because the one you normally send it to is gone. You = >can pick through this code and see what you make of it, but this should, = >by no means, be used as a complete guide to subclassing. This might, = >perhaps give you a better understanding of subclassing, or it may just = >confuse you even more. >--=20 >Hope this helps, >Jason Bouzane
>> Greetings, >> I am a newbie who made a little program that whenever I get new text >> into my clipboard it pastes that text into a listbox. I did this by >> checking the clipboard by a timer set to 1 second. I was told that >> there was a better way to do this than the timer. I was told about >> subclassing the form to recieve a message that the clipboard has >> changed. For the last several days I have been reading about >> subclassing, and SendMessage, etc. and am now more confused than >> ever:). Not sure of which functions to use or how to access the >> cliboard data once I am informed of a change. Does anyone have any >> leads about how to do this? What api functions I might need? ANd >> basically a description in simple english of how it is done so that I >> might read the right references to figure it out. Maybe a good site >> with a good description of how to subclass. Any takers? >> Mark >>=20 >------=_NextPart_000_00D7_01BF48DF.9C2D8900 >Content-Type: text/html; > charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable ><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ><HTML><HEAD> ><META http-equiv=3DContent-Type content=3D"text/html; = >charset=3Diso-8859-1"> ><META content=3D"MSHTML 5.50.3825.1300" name=3DGENERATOR> ><STYLE></STYLE> ></HEAD> ><BODY> ><DIV><FONT face=3DArial size=3D2>Subclassing is a very touchy subject = >and it is not=20 >a good idea for somebody new to programming to jump right into such a = >topic=20 >without first becoming familiar with the language. For example, when=20 >subclassing, you cannot use the Stop button or the End statement and it = >is very=20 >difficult to debug the application. If there is a bug in your = >application, your=20 >program will probably crash taking the IDE with it. Sticking with the = >one second=20 >timer really isn't such a bad idea, unless you are working with large = >amounts of=20 >text. But I will still give you a pointer to checking the clipboard. Add = >the=20 >following code to a module:</FONT></DIV><PRE>Public Declare Function = >SetClipboardViewer Lib "user32.dll" (ByVal hWnd As Long) As Long >Public Declare Function ChangeClipboardChain Lib "user32.dll" (ByVal = >hWndRemove As Long, ByVal hWndNext As Long) As Long >Public Declare Function SendMessageA Lib "user32.dll" (ByVal hWnd As = >Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As = >Long >Public Declare Function SetWindowLongA Lib "user32.dll" (ByVal hWnd As = >Long, ByVal nIndex As Integer, ByVal dwNewValue As Long) As Long >Public Declare Function CallWindowProcA Lib "user32.dll" (ByVal = >lpfnWndProc As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal = >wParam As Long, ByVal lParam As Long) As Long >Public Const WM_CHANGECBCHAIN =3D &H30D >Public Const WM_DRAWCLIPBOARD =3D &H308 >Public Const GWL_WNDPROC =3D -4 >Public hWndNext As Long >Public lpfnWndProc As Long >Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal = >wParam As Long, ByVal lParam As Long) As Long > Select Case uMsg > Case WM_DRAWCLIPBOARD > If Clipboard.GetFormat(vbCFText) Then > frmMain.lstList.AddItem
Clipboard.GetText(vbCFText) Quote: > End If > SendMessageA hWndNext, uMsg, wParam, lParam > WndProc =3D 0 > Exit Function > Case WM_CHANGECBCHAIN > If wParam =3D hWndNext Then=20 > lParam =3D hWndNext > End If > SendMessageA hWndNext, uMsg, wParam, lParam > WndProc =3D 0 > Exit Function > Case Else > WndProc =3D CallWindowProcA(lpfnWndProc, hWnd, uMsg, wParam, lParam) > Exit Function > End Select >End Function</PRE> ><DIV><FONT face=3DArial
... read more »
|
Wed, 05 Jun 2002 03:00:00 GMT |
|
|
|