|
|
Uğur Şirin wrote: Can you help me example or source code? We can help with code if you are stuck or have questions. We do not write code on demand.
Uğur Şirin wrote: I need VB6 Script Codes, use to localhost XP. VB6 is deprecated; meaning that it's no longer supported.
"Good luck".
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
When a vb6 project is converted to vb.net using visual studio's conversion wizard, all forms and its controls have appearance in that of a vb6. How to change the appearance to vb.net style?
|
|
|
|
|
Rework the form by hand. There is no automated way to do it.
Frankly, you'll probably be rewriting the app from scratch to get all the benefits of .NET.
|
|
|
|
|
Hi.
I think an answer to this problem lies in the use of delegates and marshaling, but if so, I cannot figure this one out.
In vb6, you could use the AddressOf method to get the address of a function. vb.Net no longer allows such a simple idea. Some have even suggested that you do not need to get the address of a function. Apparently they do not use API functions, where getting the address of a function is essential.
Now, in vb.Net, if you attempt to use AddressOf(SomeFunction), as in:
lPrevWndProc = SetWindowLong(hControl, GWL_WNDPROC, AddressOf WindowProc)
You get the following error:
MSDN is as obtuse as ever when describing this problem where a simple example of how to replace the as-simple-as-it-gets vb6 "AddressOf" method with a vb.Net method would have been the obvious thing to do. I reference:
http://msdn.microsoft.com/en-us/library/ms184628%28v=vs.90%29.aspx[^]
which explains no more than the IDE message does in that respect, so they might as well have not even created that link. They offer other links to study which venture off into space because...All they needed to do was offer a simple comparison of how to do in vb.Net, to what was done in vb6.
I have searched high and low for an answer and all I have found is frustration.
Any help would be greatly appreciated. HELP! SOS!
|
|
|
|
|
There is an example here[^] in c#. Just run the code through an online coverter. You may need to touch up a few lines after converting.
|
|
|
|
|
Thanks for the link! I tried it and it does not work, yet. I am assuming that WindowProc is constantly listening for events, so that no button-click handler is required (which would defeat the purpose of using the API, anyway). But as it it is written now, I think it is deaf!
Public Class Form1
Public Delegate Function Win32WndProc(ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As Integer
Private Declare Function SetWindowLong Lib "user32" (ByVal hWnd As IntPtr, _
ByVal nIndex As Integer, _
ByVal newProc As Win32WndProc) _
As IntPtr
Private Declare Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, _
ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) _
As Integer
Private Const GWL_WNDPROC As Integer = -4
Private Const WM_LBUTTONDOWN As Integer = 513
Private oldWndProc As IntPtr = IntPtr.Zero
Private newWndProc As Win32WndProc = Nothing
Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
newWndProc = New Win32WndProc(AddressOf MyWndProc)
oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc)
End Sub
Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, _
ByVal wParam As Integer, ByVal lParam As Integer) _
As Integer
Select Case (Msg)
Case WM_LBUTTONDOWN
MessageBox.Show("Clicked")
Return 0
End Select
Return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam)
End Function
End Class
|
|
|
|
|
What is that you want to accomplish? The code I referenced will work, but is restricted to re-assigning windows owned by the process that invokes it. This is a restriction imposed by the SetWindowLong function (see: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx[^]; for the doc on GWL_WNDPROC).
Here is a version that works for a TextBox on the form.
Imports System.Runtime.InteropServices
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SubclassHWnd(TextBox1.Handle)
End Sub
' Win32 API needed
<DllImport("user32")> _
Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As Win32WndProc) As IntPtr
End Function
<DllImport("user32")> _
Private Shared Function CallWindowProc(ByVal lpPrevWndFunc As IntPtr, ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
' A delegate that matches Win32 WNDPROC:
Private Delegate Function Win32WndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
' from winuser.h:
Private Const GWL_WNDPROC As Integer = -4
Private Const WM_LBUTTONDOWN As Integer = &H201
' program variables
Private oldWndProc As IntPtr = IntPtr.Zero
Private newWndProc As Win32WndProc = Nothing
Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
' hWnd is the window you want to subclass..., create a new
' delegate for the new wndproc
newWndProc = New Win32WndProc(AddressOf MyWndProc)
' subclass
oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc)
End Sub
' this is the new wndproc, just show a messagebox on left button down:
Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Select Case Msg
Case WM_LBUTTONDOWN
MessageBox.Show("Clicked")
Return 0
Case Else
Exit Select
End Select
Return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam)
End Function
'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by NRefactory.
'Twitter: @telerik, @toddanglin
'Facebook: facebook.com/telerik
'=======================================================
End Class This is pointless to do as there are other mechanisms to gain access to a textbox's WndProc method. The simplest would be to create custom textbox control and override it's WndProc method.
Public Class mtTB
Inherits TextBox
Private Const WM_LBUTTONDOWN As Integer = &H201
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
Select Case m.Msg
Case WM_LBUTTONDOWN
' do something
End Select
End Sub
End Class Or you could create a native window listener as shown here.[^]
|
|
|
|
|
Gawd I'm so stupid sometimes. I was driving home from the store today, and realized I hadn't started the listening process during form load. My version works now...You're version worked perfectly from the get-go.
But furthermore, to get mine to work, I had to change the function declarations to the "other" style.
From:
Private Declare Function SetWindowLong Lib "user32" (ByVal hWnd As IntPtr, _
ByVal nIndex As Integer, _
ByVal newProc As Win32WndProc) As IntPtr
Private Declare Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, _
ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As Integer
To:
<DllImport("user32")> _
Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, _
ByVal nIndex As Integer,
ByVal newProc As Win32WndProc) As IntPtr
End Function
<DllImport("user32")> _
Private Shared Function CallWindowProc(ByVal lpPrevWndFunc As IntPtr, _
ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As Integer
End Function
Why is one different than the other? I notice that the first is not shared and the second one is.
But I have never encountered any problems before using the first syntax.
modified 2-Jul-13 3:01am.
|
|
|
|
|
When using the "Declare" keyword, the default characterset modifier is ANSI.
From the documentation for Declare[^]
Quote:
Character Sets. You can specify in charsetmodifier how Visual Basic should marshal strings when it calls the external procedure. The Ansi modifier directs Visual Basic to marshal all strings to ANSI values, and the Unicode modifier directs it to marshal all strings to Unicode values. The Auto modifier directs Visual Basic to marshal strings according to .NET Framework rules based on the external reference name, or aliasname if specified. The default value is Ansi.
charsetmodifier also specifies how Visual Basic should look up the external procedure within its external file. Ansi and Unicode both direct Visual Basic to look it up without modifying its name during the search. Auto directs Visual Basic to determine the base character set of the run-time platform and possibly modify the external procedure name, as follows:
On an ANSI platform, such as Windows 95, Windows 98, or Windows Millennium Edition, first look up the external procedure with no name modification. If that fails, append "A" to the end of the external procedure name and look it up again.
On a Unicode platform, such as Windows NT, Windows 2000, or Windows XP, first look up the external procedure with no name modification. If that fails, append "W" to the end of the external procedure name and look it up again.
The error message you should have received was: Unable to find an entry point named 'SetWindowLong' in DLL 'user32.dll'. You could correct this like this:
Private Declare Auto Function SetWindowLong Lib "user32.dll" (ByVal hWnd As IntPtr, _
ByVal nIndex As Int16, _
ByVal newProc As Win32WndProc) As IntPtr
Private Declare Auto Function CallWindowProc Lib "user32" (ByVal lpPrevWndFunc As IntPtr, _
ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As Integer
|
|
|
|
|
Thanks for the clarification, TnTinMan. Much obliged. So much to learn...So little time!
|
|
|
|
|
|
Thank you, Bernhard!
I am testing it now.
|
|
|
|
|
That is the function, but the problem is the last argument, dwNewLong. In vb6, you could just use AddressOf dwNewLong and the world was happy. But in vb.Net you can't do that because its AddressOf() does not return an address, but a delegate object.
|
|
|
|
|
The AddressOf is fine; it's the P/Invoke declaration which is wrong. You're trying to pass a delegate to a parameter which is declared as taking an IntPtr . In unmanaged code, this would be fine, but in managed code, the parameter types need to match.
To call this method, you would need to declare an overload of the SetWindowLong method with the dwNewLong parameter declared as a WndProc delegate.
However, .NET offers much easier ways to accomplish the same thing. For example, in Windows Forms, you just need to override the WndProc method[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks Richard!
I am trying out all three suggestions to see what happens!
|
|
|
|
|
That's what I couldn't understand, was how to get the address out of the delegate. But one of the things I still get caught up with is that the documented data types for API functions are apparently not sacrosanct. I guess there is some leeway via overloading (which seems hard to find info on in the official sources). In that regard, is overloading the same as subclassing?
|
|
|
|
|
treddie wrote: is overloading the same as subclassing?
Overloading[^] means creating two or more methods with the same name but different signatures. Subclassing[^], in this context, usually means replacing the window procedure of an existing control to extend or alter its behaviour.
pinvoke.net[^] is usually a good place to start when you're looking to call an unmanaged Windows API.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
DoH!...I should have known better, but I forgot...Many years ago, I first learned about subclassing to solve a graphics issue, and should have recalled that subclasssing is, in a way, a sort of "hijacking", in that you make Windows THINK you are using a standard WindowProc(), when in fact you have redirected execution to a function of your own making. That way, Windows is satisfied, and you get to do neat stuff as a result.
|
|
|
|
|
Hi all,
I hope someone of the more experienced members watches this forum - it doesn't seem to be very frequented, but I urgently need a solution very soon. Let me also mention that I am a fairly unexperienced leisuretime programmer, and that scanning the internet and playing around with Expresso for days didn't help - so I set my hopes upon you now... Sniff | .
In my application I have to parse different file formats for regular expressions. The match patterns are divided by diffferent patterns of control characters, depending on the file format. A sample would be:
1
01:00:01:10
01:00:05:22
After the conquest and plundering
of the Inca empire by Spain
2
01:00:05:25
01:00:09:09
the Indians invented the
legend of El Dorado
3
01:00:09:12
01:00:13:24
a land of gold, located in the
swamps of the Amazon headwaters. I get fairly proper matches with this regex:
(?<Nummer>\d+)\r\n(?<TCStart>\d{2}:\d{2}:\d{2}:\d{2})\r\n(<TCEnd>\d{2}:\d{2}:\d{2}:\d{2})\r\n(?<Text>[a-zA-Z;1-9;\s;\p{P};\p{L}\p{M}]*)\r\n\r\n The problem is: If there's a '0' (zero) in the text - like e.g. in years ("this happened a.d. 1570") - the whole pattern won't match!? On the other hand, if I change "1-9" into the common "0-9" pattern, then I have only one matching result, which contains all the other supposed matches in its "Text" group.
I hope I expressed the problem in an understandable way... and I'll highly appreciate if someone could guide me to a better solution!
Thanks in advance
Mick
|
|
|
|
|
I think the Text portion could be:
(?<Text>((?!\d+\r\n).*\r\n)*)
(?!\d+\r\n) will exclude any line with number only
.* will include any line (except the lines with number only, as excluded by (?!\d+\r\n) )
Btw, I noticed you don't have ? before <TCEnd>
|
|
|
|
|
Wow - this seems to make it and even looks much simpler than what I've been fiddeling out in so many hours ! Thank you for ending my sleepless nights
BTW the ? must have got lost in the copy/paste process. It's part of the original.
Have a very nice weekend,
thank you very much!
|
|
|
|
|
Hi all.
Sorry for the frustration here, but I always dread going to MS for any kind of help anymore, regarding what this-or-that does. For years now, they are extremely spotty in their ability to describe something simply and unambiguously. Below is a perfect example; a paragraph which talks in circles:
"The WithEvents statement and the Handles clause provide a declarative way of specifying event handlers. An event raised by an object declared with the WithEvents keyword can be handled by any procedure with a Handles statement for that event, as shown in the following example:"
Sounds like lawyer talk, so whenever I run into lawyer talk, I try to reword it into an explicit example. So here goes.
"A button's mouse click event raised by a button, declared with the WithEvents keyword can be handled by any procedure with a Handles statement for the button mouse click event..."
That's like saying "A box with a lid, has a lid on it."
It seems to be saying that if I use the WithEvents keyword, I can attach, for example, the statement, "Handles Button3.Click" on to ANY procedure and the procedure will respond to the Button3.Click event. Well...Duh! I can do that withOUT the WithEvents keyword! So what is the difference?
Or did they MEAN to say,
"A user can declare a custom event with the WithEvents keyword. Then, any procedure can use that event just like any other event, by attaching it at the end of a procedure's declaration, with the "Handles" clause."
If so, why use the keyword "WithEvents at all? Why not just,
Public Event MyCustomEvent
End Event
OR, are they trying to say this,
'Using the WithEvents keyword, a class is declared that can contain multiple events, any of which can be used at the end of a procedure's declaration with the "Handles" clause. For example,
Dim WithEvents MyEventsCollection As New EventsCollection1
Class EventsCollection1
Public Event My1stEvent()
Public Event My2ndEvent()
End Class
'Then, any procedure can have a Handles clause at the end of it, which assigns any of the events in the collection,
Private Sub ThisProcedure() Handles EventsCollection1.My1stEvent
End Sub
If THAT is what they mean, why put all of those events in a collection (a Class), instead of just calling them all out individually? That is a lot less work:
Private Sub ThisPrcoedure() Handles My1stEvent, My2ndEvent
End Sub
Please help me straighten this out, since I am obviously missing something really important about WithEvents that MS can't explain without ambiguity.
|
|
|
|
|
treddie wrote: If so, why use the keyword "WithEvents at all? Why not just,
"VB6"
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Do you mean that it is a left-over from vb6?
|
|
|
|
|