Monday, December 29, 2008
How to Expose the Events of a Custom Control in the Parent Form
There are actually a number of ways to do this. Below are three ways:
1. The easiest way to do this is to just raise an event in the Custom Control and handle that event in the Form.
Public Event LinkClicked(ByVal sender As Object, ByVal e As EventArgs)
Private Sub LinkLabel1_LinkClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
RaiseEvent LinkClicked(sender, e)
End Sub
2. Another way is to have a PictureBox value in the form point to the PictureBox that is on the control. And then address the Mouse events there. You'll need a way to return the Control to you via a FindControl routine in your Custom Control
Public Function FindControl(ByVal Name As String) As Control
For Each c As Control In Me.Controls
If c.Name.ToLower = Name.ToLower Then
Return c
End If
Next
End Function
Then in your Form you would do the following:
WithEvents MyFullImage As PictureBox
And in your Form_Load event:
MyFullImage = ImgEditor1.FindControl("FullImage") 'This is assuming the FullImage is the name of the Picturebox in your Control
And then you can do the following:
Private Sub MyFullImage_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyFullImage.MouseDown
End Sub
3. Lastly you would still use the FindControl mentioned in method 2, but do the following
'Add this to form_load
Dim pctBox as PictureBox = MyUserControl1.FindControl("FullImage")
AddHandler pctBox.Click, AddressOf TestClick
Private Sub TestClick(ByVal sender As Object, ByVal e As System.EventArgs)
MsgBox("Testing AddHandler Method")
End Sub
Wednesday, December 24, 2008
Referenced DLL kept getting deleted in vb.net project
Tuesday, December 23, 2008
Passing an array of Structures with an array to unmanaged code from VB.NET
What ended up fixing my problem was that in my structure was a Boolean variable. When I changed that Boolean to Integer then all of a sudden everything worked.
I'll post code samples shortly.
Wednesday, December 10, 2008
Stop the Windows Authentication in Firefox
Whenever I have to go to the know or to timecard or to a teamsite, I get this dialog box which prompts me to enter a username and password in firefox. I don't get this in IE. The fix in firefox is this:
1. Open Firefox
2. Navigate to the url about:config
3. Locate the following preference names and put as the value the comma separated values of the address roots.
network.automatic-ntlm-auth.trusted-uris
network.negotiate-auth.delegation-uris
network.negotiate-auth.trusted-uris
Your value should look something like this: localhost,companyname.org
Wednesday, November 26, 2008
How to avoid auto checkout in VS 2005
Can't find Source Control unter Tools->Options in VS 2005
Thursday, November 13, 2008
How to copy files between your local computer and one connected through Remote Desktop
From Microsoft (http://support.microsoft.com/kb/313292):
To view the disk drives and files for the redirected disk drive. From your local machine.
1. Click Start, point to All Programs (or Programs), point to Accessories, point to Communications, and then click Remote Desktop Connection. Or if you don't see the option, click Start->Run-> and type in mstsc.exe and hit enter.
2. Click Options, and then click the Local Resources tab.
3. Click Disk Drives, and then click Connect. Or, click the More button and then check the Drives checkbox.
Wednesday, November 12, 2008
How to tell if you can run Windows Vista 64 bit
a.If your Start menu is configured for Classic Start menu, right-click the My Computer icon on your desktop, and click Properties.
b.If your Start menu is the Windows default Start menu, click the Start button, then right-click the My Computer icon in your Start menu, and click Properties.
2.Click the Advanced tab.
3.Click Environment Variables.
4.In the "System variables" list at the bottom of the Environment Variables window, look for a variable called "PROCESSOR_ARCHITECTURE". If your PC has a 32-bit processor, this variable will have a value of "x86". If it has a 64-bit processor this variable will have a value of "x64".
Problems on Vista 64 bit operating systems
1.Click on Tools...Options
2.Select Projects and Solutions
3.Check the Show advanced build configurations option and click the OK button
1.Click on Build...Configuration Manager
2.Click on the Platform dropdown for your project in the list and select <New...>
3.In the Project Platform dialog select x86 from the new Platform dropdown and click OK
What is WoW mean
Thursday, October 23, 2008
Interpolate an array to twice its size in VB.NET
011000
Now this array is a one dimensional array that contains values for an image. For this example, the width of the image is 2 digits. I wanted to interpolate this array so that the width of the image is 4 digits.
Initially my thought was just to do this:
001111000000
This was simple as I just looped through the original array as such:
for index = 0 to oldarray.length - 1
newarray[index*2] = oldarray[index]
newarray[index*2 + 1] = oldarray[index]
end for
But the problem with this is that the old image looked like this:
01
10
00
The new image looks like this:
0011
1100
0000
Which is fine, except when I realized that I interpolated ONLY the WIDTH of the array, and not the height. What I wanted was something like this:
001100111100110000000000
0011
0011
1100
1100
0000
0000
Now for some reason I couldn't figure this out. But the solution is actually quite simple. You have to set 4 values for each one in the old array. In the above example, I interpolate the width, now I just need to interpolate the height. Below is the example.
For index As Integer = 0 To oldarray.length - 1
If (index > 0 AndAlso (index Mod NEWARRAYWIDTH/ 2))) = 0) Then // I know what the width of the new image will be, and the old one is half as large
row = row + 1
End If
newIndex = index Mod CInt((NEWARRAYWIDTH / 2))
nearray((row * 2) * NEWARRAYWIDTH + (newIndex * 2)) = oldarray(index)
nearray((row * 2) * NEWARRAYWIDTH + ((newIndex * 2) + 1)) = oldarray(index)
nearray(((row * 2) + 1) * NEWARRAYWIDTH + (newIndex * 2)) = oldarray(index)
nearray(((row * 2) + 1) * NEWARRAYWIDTH + ((newIndex * 2) + 1)) = oldarray(index)
Next
I installed VS 2003 after VS 2005
Thursday, October 16, 2008
Missing MSVCR80.dll and COREDLL.DLL
Wednesday, October 1, 2008
How to Save the Output of a Paint Routine in .NET to a Bitmap File or save the image from a picturebox to a bitmap file
I have a Picture box where I load an image at design time. At runtime, I allow the user the doodle on the image. I would like to save this image to a bitmap file. The way I allow the user to draw on the image is through the mousedown and mousemove event I write to an arraylist, and in the PictureBox's paint routine I draw out the contents of the arraylist. When I try to do a Picturebox1.Image.Save, it doesn't work in that it saves the original image that I loaded at design time, not the one that I just drew on in mousedown and mousemove. There are two ways the do this. The harder method is below. What it does is it creates a tempimage, then it draws to this temp image (what I am assuming here is that you've moved the code from your PictureBox1.Paint routine to a stand alone routine called PaintPictureBox1, this way you can call it from two places), and finally it returns the temp image.
Public Function CurrentPictureBox() as Bitmap
Dim iNewWidth As Integer, iNewHeight As Integer
iNewWidth = Int(PictureBox1.Image.Width)
iNewHeight = Int(PictureBox1.Image.Height)
tempImage = New Bitmap(iNewWidth, iNewHeight, System.Drawing.Imaging.PixelFormat.Format32bppRgb)
g = Graphics.FromImage(tempImage)
g.DrawImage(PictureBox1.Image, 0, 0, iNewWidth, iNewHeight)
PaintPictureBox1(g)
return tempImage
End Sub
The second method is simpler, in that it takes advantage of .NETs DrawToBitmap routine.
Public Function CurrentPictureBox() as Bitmap
Dim tempImageAs New Drawing.Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height)
PictureBox1.DrawToBitmap(tempImage, New Rectangle(0, 0, bmp.Width, bmp.Height))
return tempImage
End Sub
Wednesday, September 24, 2008
How to get the index (GetIndex) from a ToolStripMenuItem
Public Sub MenuBrushSize_Click(ByVal eventSender As System.Object, ByVal e As System.EventArgs) Handles MenuBrushSize.Click
Dim Index As Short = MenuBrushSize.GetIndex(eventSender)
Select Case Index
Case 0
'do something
Case 1
'do something
Case 2
'do something
Case Else
'do something
End Select
End Sub
When I moved over to 2005 and decided to use the ContextMenuStrip and subsequently the ToolStripMenuItem, I decided not to use the VB6.MenuItemArray. But then I didn't want to have separate handler routines for each and every one of my menu items. I wanted to have it all in one Subroutine. But there isn't a GetIndex function for the ToolStripMenuItem. So I had to create one, below is how I was able to do it:
Public Function GetMenuItemIndex(ByVal sender As System.Object) As Short
Dim oMenuItem As New System.Windows.Forms.ToolStripMenuItem
oMenuItem = CType(sender, System.Windows.Forms.ToolStripMenuItem)
If TypeOf oMenuItem.Owner Is ContextMenuStrip Then
Dim parentMenu As ContextMenuStrip = oMenuItem.Owner
For index As Integer = 0 To parentMenu.Items.Count - 1
If oMenuItem.Name = parentMenu.Items(index).Name Then
Return index
End If
Next
ElseIf TypeOf oMenuItem.Owner Is ToolStrip Then
Dim parentMenu As ToolStrip = oMenuItem.Owner
For index As Integer = 0 To parentMenu.Items.Count - 1
If oMenuItem.Name = parentMenu.Items(index).Name Then
Return index
End If
Next
End If
End Function
This function basically checks the parent of the current menu, and gets the index of that menu item. Basically I assume the menu item is part of some collection and I want to find out the index in the collection.
Below is how I use it. Its pretty much the same, execept now my handles must specify all the menu items we are handling.
Public Sub MenuBrushSize_Click(ByVal eventSender As System.Object, ByVal e As System.EventArgs) Handles _
MenuBrushSize_0.Click, MenuBrushSize_1.Click, MenuBrushSize_2.Click, MenuBrushSize_3.Click
Dim Index As Short = GetMenuItemIndex(eventSender)
Select Case Index
Case 0
'do something
Case 1
'do something
Case 2
'do something
Case Else
'do something
End Select
End Sub
ContextMenuStrip is not modal like ContextMenu
Menu.Show(Me.Image, e.x, e.y)
'Followed by a block of code
Block of code
The thing is my application didn't expect to execute the block of code until after the user selected the menu item. So basically, when Menu.Show was called, we waited until the user clicked the menu item (at which point the code in the .Click) routine was called, and then we executed "Block of code"
Recently, I "updated" my application and decided to use the ContextMenuStrip for my menu. Well, what happens now is after the Show method is called, the Block of code is executed immediately. Which screws me up.
Haven't yet figured out a solution for this.
Wednesday, September 10, 2008
Saving global variables to an XML file
Here's a practical example of a technique that I used in several real applications. I gather all the global variables in a class named something like Globals or ProjectData that I can persist to an XML file stored on disk. To leverage the XML serialization mechanism offered by the .NET Framework, these global variables must be implemented as instance fields, but at the same time the class must be exposed as a singleton so that it can be accessed from anywhere in the application. Here's how you can build such a class:
' This code requires a reference to the System.Xml.dll assembly.
' (Classes must be public to use XML serialization.)
Public Class Globals
' This singleton instance is created when the application is created.
Private Shared m_Value As New Globals
' This static read-only property returns the singleton instance.
Public Shared ReadOnly Property Value() As Globals
Get
Return m_Value
End Get
End Property
' Load the singleton instance from file.
Public Shared Sub Load(ByVal fileName As String)
' Deserialize the content of this file into the singleton object.
Using fs As New FileStream(fileName, FileMode.Open)
Dim xser As New XmlSerializer(GetType(Globals))
m_Value = DirectCast(xser.Deserialize(fs), Globals)
End Using
End Sub
' Save the singleton instance to file.
Public Shared Sub Save(ByVal fileName As String)
' Serialize the singleton object to the file.
Using fs As New FileStream(fileName, FileMode.Create)
Dim xser As New XmlSerializer(GetType(Globals))
xser.Serialize(fs, m_Value)
End Using
End Sub
' Instance fields (the global variables)
Public UserName As String
Public Documents() As String
Public UseSimplifiedMenus As Boolean = True
Public UseSpellChecker As Boolean = True
End Class
Using the Globals class is straightforward because you must simply invoke the Load static method after the application starts and the Save static method before the application terminates. All the global variables can be accessed as properties of the Globals.Value object, as follows:
Globals.Value.UserName = "Francesco"
' Assign two items to the Documents array.
Globals.Value.Documents = New String(){"c:\doc1.txt", "c:\doc2.txt"}
' Save current global variables on disk.
Globals.Save("c:\myapp\globals.xml")
Interestingly, the very first time a given user runs the application, the XML file doesn't exist, thus the singleton Globals object will contain the default values for global variables you've defined by means of initializers.
Note | Visual Basic 2005 comes with a very powerful mechanism for saving and retrieving user settings, which is conceptually similar to the one I illustrate in this section. You can read more about it in Chapter 16, "The My Namespace." However, the technique I just illustrated is more generic and flexible than the built-in Visual Basic mechanism is and can be used in many circumstances in which the built-in approach wouldn't work. For one, the built-in technique can store only one set of values for each user, and you can't manage multiple sets of preferences for a given user, merge current options with other users, move options to other computers, and so forth. |
Wednesday, September 3, 2008
Official XML Comment Tags for .NET
The "official" XML comment tags
The following XML comment tags are officially supported in VB.NET: c,code, example, exception, include, list, para, param, paramref, permission, remarks, returns, see, seealso, summary and typeparam.
c: This tag is used to denote code, so it can be used to identify sample code associated with a particular entity within the source code. Note that the tag can only be used to represent a single line of code or to denote that some of the text on a line should be marked up as code. Example: <c>Dim MyObject As MyType</c>
code: This tag is used to denote more than one line of code, so it can be used to identify longer areas of sample code.
example: This tag may be used to describe an example of using a particular method or class. It is possible to include code samples within the example tag by making use of either the c or code tags.
exception: The exception tag allows a method's exception handling to be documented. The cref attribute allows the namespace of the exception handler to be included. Example: <exception cref="System.Exception" >Throws an exception if the customer is not found.</exception>
include: This tag allows documentation to be imported from an external XML file rather than being stored within the source code itself. As such it may be useful if the documentation is written by people other than the software developers (e.g. technical writers).
list: This tag allows bulleted or numbered lists or tables to be added to XML comments.
para: This tag indicates that the text within the tags should be formatted within a paragraph. As such it can be used to format text within other tags such as summary or returns. Example: <para>This is a paragraph</para>
param: The param tag is used to document a method's arguments. The tag's name attribute specifies the name of the argument to which the tag refers. The tag is also used by Visual Studio's Intellisense system to show a description of a method's arguments. It is also used by the Visual Studio Object Browser. Example: <param name="FileName" >The filename of the file to be loaded.</param>
paramref: This tag can be used to refer to a method's argument elsewhere within the method's XML comments. The tag's name attribute specifies the name of the argument to which the tag refers. Note that the param tag is actually used to describe the parameter. Example: Use the <paramref name="FileName"/> argument to specify which filename is loaded.
permission: The permission tag can be used to describe any special permissions a specific object needs. The object to which the permission refers is included as the cref attribute. Example: Class needs to write to the file system, ensure user has appropriate access.
summary: The summary tag describes a method or class, so it is the most important tag. As well as being used in a project's documentation, the tag is also used by Visual Studio's Intellisense system to show a description of the method or class being referenced. It is also used by the Visual Studio Object Browser.
remarks: The remarks tag can be used to supply additional information about a method or class, supplementing the details given in the summary tag. As with the summary tag, this tag is also used by Visual Studio's Intellisense system and the Visual Studio Object Browser.
returns: Describes the return value of a method. Example: <returns>True if user has permission to access the resource, otherwise False.</returns>
see: The see tag is used to reference other entities (such as classes) in the project. The see tag is intended for use within other tags such as the summary tag. Example: <seealso cref="System.Configuration"/>
seealso: The seealso tag resembles the see tag and has identical syntax, except that the text is intended to be used to create a separate seealso section for the entity's documentation.
typeparam: Typeparam is used in an identical way to param, except that it is used to document a type associated with a generic class or function.
value: Value is only used when documenting a property, and is used to describe the value assigned to that. The comment is not required for properties that are marked as read only. Example: <value>Sets the employee's salary</value>
Wednesday, July 16, 2008
How to update or refresh a Typed DataSet (xsd file) in the DataSet Designer in Visual Studio
In my situation, my dataset was populated by a stored procedure. So I had to go into Microsoft Sql Server Management Studio Express, Go the Programmability Folder/Stored Procedures and find my stored procedure. right click it and select modify, then add the new column and execute it.
Then back in Visual Studio, I had to right click on my Dataset Table and select "Configure Dataset with Wizard" and expand the Stored Procedures, then find my stored procedure and at the bottom was the new column that I added. Just check the column name and it was added to the dataset.
the above paragraph would probably also apply even if you didn't have a Stored Procedure by your main engine, as you could add and remove tables using the "Configure Dataset with Wizard".
-- Ted
Sunday, July 13, 2008
BannerBitmap conflicts with BannerText
http://www.bokebb.com/dev/english/1993/posts/199395473.shtml
Add My App to the Open With Menu
I searched on the internets with no solution. A fair number of people asked this question, like this person
http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.windowsforms/topic59830.aspx
but no answers.
I tried different things in the Setup part of the application with no luck. Finally, I realized the issue was with the MUICache value in the Registry, however I did not want to run a .reg file after the install.
Finally, I stumbled upon the answer, and it seems to be setting the AssemblyDescription value in the AssemblyInfo.vb file of your main executable. What's odd is that in the recent past, I tried setting some values here and it didn't make a difference.
The key might have to do is that fact that there was a blank values in the MUICache for my application, and once I deleted the key associated with my application from the MUICache then it registered. On that note, it could be the AssemblyDescription, AssemblyTitle or AssemblyProduct values as they all have the same value. I'll need to do more testing to verify exactly which one is the key value to be filled out.
Also, the MUICache values don't get removed when you uninstall your application.
Update
The above technique basically is crap. It only works if the entry doesn't exist in the MUICache. What I mean by that is if you have a blank entry in the MUICache, delete it, then install your application (or just launch it), a new entry will now be in the MUICache with the proper information. For some reason, a previous verison of mine entered a blank value into the MUICache, and now i can't get rid of it, or overwrite it through the install. I'd rather not remove it from my code, but I might end up having to.
Thursday, July 3, 2008
Constants for WND_Proc overrides
Public Const WM_USER As Integer = &H400
Public Const WM_NULL As Integer = &H0
Public Const WM_CREATE As Integer = &H1
Public Const WM_DESTROY As Integer = &H2
Public Const WM_MOVE As Integer = &H3
Public Const WM_SIZE As Integer = &H5
Public Const WM_ACTIVATE As Integer = &H6
Public Const WM_SETFOCUS As Integer = &H7
Public Const WM_KILLFOCUS As Integer = &H8
Public Const WM_ENABLE As Integer = &HA
Public Const WM_SETREDRAW As Integer = &HB
Public Const WM_SETTEXT As Integer = &HC
Public Const WM_GETTEXT As Integer = &HD
Public Const WM_GETTEXTLENGTH As Integer = &HE
Public Const WM_PAINT As Integer = &HF
Public Const WM_CLOSE As Integer = &H10
Public Const WM_QUERYENDSESSION As Integer = &H11
Public Const WM_QUIT As Integer = &H12
Public Const WM_QUERYOPEN As Integer = &H13
Public Const WM_ERASEBKGND As Integer = &H14
Public Const WM_SYSCOLORCHANGE As Integer = &H15
Public Const WM_ENDSESSION As Integer = &H16
Public Const WM_SHOWWINDOW As Integer = &H18
Public Const WM_WININICHANGE As Integer = &H1A
Public Const WM_DEVMODECHANGE As Integer = &H1B
Public Const WM_ACTIVATEAPP As Integer = &H1C
Public Const WM_FONTCHANGE As Integer = &H1D
Public Const WM_TIMECHANGE As Integer = &H1E
Public Const WM_CANCELMODE As Integer = &H1F
Public Const WM_SETCURSOR As Integer = &H20
Public Const WM_MOUSEACTIVATE As Integer = &H21
Public Const WM_CHILDACTIVATE As Integer = &H22
Public Const WM_QUEUESYNC As Integer = &H23
Public Const WM_GETMINMAXINFO As Integer = &H24
Public Const WM_PAINTICON As Integer = &H26
Public Const WM_ICONERASEBKGND As Integer = &H27
Public Const WM_NEXTDLGCTL As Integer = &H28
Public Const WM_SPOOLERSTATUS As Integer = &H2A
Public Const WM_DRAWITEM As Integer = &H2B
Public Const WM_MEASUREITEM As Integer = &H2C
Public Const WM_DELETEITEM As Integer = &H2D
Public Const WM_VKEYTOITEM As Integer = &H2E
Public Const WM_CHARTOITEM As Integer = &H2F
Public Const WM_SETFONT As Integer = &H30
Public Const WM_GETFONT As Integer = &H31
Public Const WM_SETHOTKEY As Integer = &H32
Public Const WM_GETHOTKEY As Integer = &H33
Public Const WM_QUERYDRAGICON As Integer = &H37
Public Const WM_COMPAREITEM As Integer = &H39
Public Const WM_GETOBJECT As Integer = &H3D
Public Const WM_COMPACTING As Integer = &H41
Public Const WM_OTHERWINDOWCREATED As Integer = &H42
Public Const WM_OTHERWINDOWDESTROYED As Integer = &H43
Public Const WM_COMMNOTIFY As Integer = &H44
Public Const WM_WINDOWPOSCHANGING As Integer = &H46
Public Const WM_WINDOWPOSCHANGED As Integer = &H47
Public Const WM_POWER As Integer = &H48
Public Const WM_COPYDATA As Integer = &H4A
Public Const WM_CANCELJOURNAL As Integer = &H4B
Public Const WM_NOTIFY As Integer = &H4E
Public Const WM_INPUTLANGCHANGEREQUEST As Integer = &H50
Public Const WM_INPUTLANGCHANGE As Integer = &H51
Public Const WM_TCARD As Integer = &H52
Public Const WM_HELP As Integer = &H53
Public Const WM_USERCHANGED As Integer = &H54
Public Const WM_NOTIFYFORMAT As Integer = &H55
Public Const WM_CONTEXTMENU As Integer = &H7B
Public Const WM_STYLECHANGING As Integer = &H7C
Public Const WM_STYLECHANGED As Integer = &H7D
Public Const WM_DISPLAYCHANGE As Integer = &H7E
Public Const WM_GETICON As Integer = &H7F
Public Const WM_SETICON As Integer = &H80
Public Const WM_NCCREATE As Integer = &H81
Public Const WM_NCDESTROY As Integer = &H82
Public Const WM_NCCALCSIZE As Integer = &H83
Public Const WM_NCHITTEST As Integer = &H84
Public Const WM_NCPAINT As Integer = &H85
Public Const WM_NCACTIVATE As Integer = &H86
Public Const WM_GETDLGCODE As Integer = &H87
Public Const WM_SYNCPAINT As Integer = &H88
Public Const WM_NCMOUSEMOVE As Integer = &HA0
Public Const WM_NCLBUTTONDOWN As Integer = &HA1
Public Const WM_NCLBUTTONUP As Integer = &HA2
Public Const WM_NCLBUTTONDBLCLK As Integer = &HA3
Public Const WM_NCRBUTTONDOWN As Integer = &HA4
Public Const WM_NCRBUTTONUP As Integer = &HA5
Public Const WM_NCRBUTTONDBLCLK As Integer = &HA6
Public Const WM_NCMBUTTONDOWN As Integer = &HA7
Public Const WM_NCMBUTTONUP As Integer = &HA8
Public Const WM_NCMBUTTONDBLCLK As Integer = &HA9
Public Const WM_KEYFIRST As Integer = &H100
Public Const WM_KEYDOWN As Integer = &H100
Public Const WM_KEYUP As Integer = &H101
Public Const WM_CHAR As Integer = &H102
Public Const WM_DEADCHAR As Integer = &H103
Public Const WM_SYSKEYDOWN As Integer = &H104
Public Const WM_SYSKEYUP As Integer = &H105
Public Const WM_SYSCHAR As Integer = &H106
Public Const WM_SYSDEADCHAR As Integer = &H107
Public Const WM_KEYLAST As Integer = &H108
Public Const WM_INITDIALOG As Integer = &H110
Public Const WM_COMMAND As Integer = &H111
Public Const WM_SYSCOMMAND As Integer = &H112
Public Const WM_TIMER As Integer = &H113
Public Const WM_HSCROLL As Integer = &H114
Public Const WM_VSCROLL As Integer = &H115
Public Const WM_INITMENU As Integer = &H116
Public Const WM_INITMENUPOPUP As Integer = &H117
Public Const WM_MENUSELECT As Integer = &H11F
Public Const WM_MENUCHAR As Integer = &H120
Public Const WM_ENTERIDLE As Integer = &H121
Public Const WM_CTLCOLORMSGBOX As Integer = &H132
Public Const WM_CTLCOLOREDIT As Integer = &H133
Public Const WM_CTLCOLORLISTBOX As Integer = &H134
Public Const WM_CTLCOLORBTN As Integer = &H135
Public Const WM_CTLCOLORDLG As Integer = &H136
Public Const WM_CTLCOLORSCROLLBAR As Integer = &H137
Public Const WM_CTLCOLORSTATIC As Integer = &H138
Public Const WM_MOUSEFIRST As Integer = &H200
Public Const WM_MOUSEMOVE As Integer = &H200
Public Const WM_LBUTTONDOWN As Integer = &H201
Public Const WM_LBUTTONUP As Integer = &H202
Public Const WM_LBUTTONDBLCLK As Integer = &H203
Public Const WM_RBUTTONDOWN As Integer = &H204
Public Const WM_RBUTTONUP As Integer = &H205
Public Const WM_RBUTTONDBLCLK As Integer = &H206
Public Const WM_MBUTTONDOWN As Integer = &H207
Public Const WM_MBUTTONUP As Integer = &H208
Public Const WM_MBUTTONDBLCLK As Integer = &H209
Public Const WM_MOUSELAST As Integer = &H209
Public Const WM_PARENTNOTIFY As Integer = &H210
Public Const WM_ENTERMENULOOP As Integer = &H211
Public Const WM_EXITMENULOOP As Integer = &H212
Public Const WM_MDICREATE As Integer = &H220
Public Const WM_MDIDESTROY As Integer = &H221
Public Const WM_MDIACTIVATE As Integer = &H222
Public Const WM_MDIRESTORE As Integer = &H223
Public Const WM_MDINEXT As Integer = &H224
Public Const WM_MDIMAXIMIZE As Integer = &H225
Public Const WM_MDITILE As Integer = &H226
Public Const WM_MDICASCADE As Integer = &H227
Public Const WM_MDIICONARRANGE As Integer = &H228
Public Const WM_MDIGETACTIVE As Integer = &H229
Public Const WM_MDISETMENU As Integer = &H230
Public Const WM_DROPFILES As Integer = &H233
Public Const WM_MDIREFRESHMENU As Integer = &H234
Public Const WM_CUT As Integer = &H300
Public Const WM_COPY As Integer = &H301
Public Const WM_PASTE As Integer = &H302
Public Const WM_CLEAR As Integer = &H303
Public Const WM_UNDO As Integer = &H304
Public Const WM_RENDERFORMAT As Integer = &H305
Public Const WM_RENDERALLFORMATS As Integer = &H306
Public Const WM_DESTROYCLIPBOARD As Integer = &H307
Public Const WM_DRAWCLIPBOARD As Integer = &H308
Public Const WM_PAINTCLIPBOARD As Integer = &H309
Public Const WM_VSCROLLCLIPBOARD As Integer = &H30A
Public Const WM_SIZECLIPBOARD As Integer = &H30B
Public Const WM_ASKCBFORMATNAME As Integer = &H30C
Public Const WM_CHANGECBCHAIN As Integer = &H30D
Public Const WM_HSCROLLCLIPBOARD As Integer = &H30E
Public Const WM_QUERYNEWPALETTE As Integer = &H30F
Public Const WM_PALETTEISCHANGING As Integer = &H310
Public Const WM_PALETTECHANGED As Integer = &H311
Public Const WM_HOTKEY As Integer = &H312
Public Const WM_PRINT As Integer = &H317
Public Const WM_PRINTCLIENT As Integer = &H318
Public Const WM_PENWINFIRST As Integer = &H380
Public Const WM_PENWINLAST As Integer = &H38F
Tuesday, July 1, 2008
System.IO.FileNotFoundException: Could not load file or assembly 'stdole, Version=7.0.3300.0
http://forums.msdn.microsoft.com/en/clr/thread/426dfa9c-1ab7-4b3e-9474-99edb377fcb6/
To summarize:
1. Right click on the stdole.dll in the reference section of project and select local copy true. By default it will be false. This will tell the application not to get it from the GAC.
2. Add the file to your application. In your setup application, go to View->Editor->File System. In the pane that opens up, right click and select Add->Assembly. Go to the following location:C:\Program Files\Microsoft.NET\Primary Interop Assemblies and select stdole.dll.
Recompile your application and it should now work.
Below are some other suggestions:
- Remove the reference from your project (I couldn't do this as I use an old FlexGrid and it used it).
- In "Project-Properties" - "Publish" - "Application Files..." - "stdole.dll" set "publish Status" to "Include". (I already had the file included when I got the problem).
- From the command-line run gacutil with the stdole.dll. This is a workaround to get it up and running fast, but defeats the idea of having a setup application.
some other sites where people asked this question:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=9506&SiteID=1
http://forums.msdn.microsoft.com/en-US/vbgeneral/thread/17d097ae-9465-4a0d-82f1-5005b7dc26e0/
Wednesday, June 25, 2008
Find ComboBox disappeared in VS 2005
http://forums.asp.net/p/1109112/1709908.aspx
The solution:
1. Right click the toolbar
2. Select Customize...
3. Drag and drop the "Edit | Go To Find Combo" from "Commands" tab to the Standard toolbar.
Monday, June 16, 2008
Bitmap Clone vs new Bitmap vs ???
In Class1.Function1 I had the following:
public Bitmap Functon1(string tempFileName)
{
Bitmap bm;
System.IO.FileStream fs;
fs = new FileStream(tempFileName, FileMode.Open, FileAccess.Read);
try
{
bm = (Bitmap)System.Drawing.Bitmap.FromStream(fs);
}
catch
{
throw;
}
finally
{
fs.Close(); // I want to make sure the stream is closed
}
return (Bitmap)bm.Clone();
}
I placed the returned Bitmap into an ArrayList, called ListType. Later on in the program I did the following and got the GDI+ error:
pic.Image = (Bitmap)ListType[i];
Bitmap tempImage = (Bitmap)pic.Image.Clone();
tempImage.Save(@"c:\temp\file.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
One solution was to replace, and I no longer got my error.
Bitmap tempImage = (Bitmap)pic.Image.Clone();
With
Bitmap tempImage = new Bitmap(pic.Image);
That seemed to work. However, another developer that was using my program was using an Image Library that did a deep clone, and whenever he ran his clone method on the image in my ArrayList he got the GDI+ error. Therefore, I felt that I had to change my Function1. I found a solution on the following website:
http://forums.msdn.microsoft.com/en-US/netfxbcl/thread/970a7951-19f3-4ca3-8061-683b96c11a88/
The solution in my Function was:
static public Bitmap Function1 (string tempFileName)
{
try
{
using (FileStream fs = new FileStream(@tempFileName, FileMode.Open))
{
int len = (int)fs.Length;
byte[] buf = new byte[len];
fs.Read(buf, 0, len);
using (MemoryStream ms = new MemoryStream(buf))
{
return new Bitmap(ms);
}
}
}
This solved the problem when the other developer called his deep clone method. The explanation from the author of this block of code was:
GDI+ holds on to the stream handle and puts a lock on the file. Cloning is handled by GDI+, it probably copies the file handle too. You'll find that saving back the image to the same file will generate an exception too. The workaround is to load the image into memory first so GDI+ can't lock anything. For example:
Anyways, thats about it.
-- Ted
Thursday, June 12, 2008
"The page cannot be displayed" error for chm files
Get VSS Password & User ID auto-entered by VSS
To get your VSS password & user ID auto-entered by VSS you need to define environment variables that contain this info.
Here is how to do it:1. Right-click My Computer and then click Properties.
2. In the System Properties dialog box, click Advanced, and then click Environment Variables.
3. Under User variables click New.
4. In the New User Variable dialog box, in the Variable name box, type "SSUSER".
5. In the Variable Value box, type your VSS username, and then click Ok.
6. Repeat these steps to add "SSPWD" as an environment variable whose value is your VSS password.
Convert a Bitmap to a Raw Image in C#
/// <summary>
/// Convert a bitmap to a byte array
/// </summary>
/// <param name="bitmap">image to convert</param>
/// <returns>image as bytes</returns>
private byte[] ConvertBitmap(Bitmap bitmap)
{
//Code excerpted from Microsoft Robotics Studio v1.5
BitmapData raw = null; //used to get attributes of the image
byte[] rawImage = null; //the image as a byte[]
try
{
//Freeze the image in memory
raw = bitmap.LockBits(
new Rectangle(0, 0, (int)bitmap.Width, (int)bitmap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb
);
int size = raw.Height * raw.Stride;
rawImage = new byte[size];
//Copy the image into the byte[]
System.Runtime.InteropServices.Marshal.Copy(raw.Scan0, rawImage, 0, size);
}
finally
{
if (raw != null)
{
//Unfreeze the memory for the image
bitmap.UnlockBits(raw);
}
}
return rawImage;
}
Tuesday, May 27, 2008
GetPath in VB.NET 2005
System.Reflection.Assembly.GetExecutingAssembly.Location without actually knowing what I was doing, but it worked and I was getting the location of the path,
However, in VB.NET 2005, this stopped working and the path it would give me was something like:
C:\Documents And Settings\......\LocalSettings\Application Data\Microsoft\VisualStudio\8.0\ProjectAssemblies\_ean0rwersws\.....
Now the "eanOrwersws" was a random folder that it generated whenever I rebuilt the application. This seemed odd to me.
It turns out that the better way to get the Path of the application is to use one of the following calls:
System.Windows.Forms.Application.StartupPath <-- This returns the path without a "\"
I can't tell the difference between the following two calls, but they both return the path with a "\" at the end.
System.AppDomain.CurrentDomain.BaseDirectory()
AppDomain.CurrentDomain.SetupInformation.ApplicationBase()
Wednesday, May 21, 2008
Detect the Shift, Ctrl, Return Key pressed at the same time
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Select Case e.KeyCode
Case Keys.Enter
If e.Shift And e.Control Then
Debug.Write("all three pressed")
End If
End Select
End Sub
The MSDN documentation has an example where you use the e.Modifiers value, and to be honest at this point I am not sure how that value gets set. But the above procedure does work.
-- Ted
Wednesday, May 14, 2008
Missing References Folder in Solution Explorer in VS2005
Thursday, May 1, 2008
Update - Datagridview - Sorting Numeric Columns that are not bound...
Private Sub grd_SortCompare(ByVal sender As
e.SortResult = CompareEx(e.CellValue1.ToString, e.CellValue2.ToString)
e.Handled = True
Exit Sub
End Sub
Public Function CompareEx(ByVal s1 As Object, ByVal s2 As Object) As Integer
Try
' convert the objects to string if possible.
Dim a As String = CType(s1, String)
Dim b As String = CType(s2, String)
' If the values are the same, then return 0 to indicate as much
If s1 = s2 then return 0
' Look to see if either of the values are numbers
Dim IsNum1 As Boolean = IsNumeric(a)
Dim IsNum2 As Boolean = IsNumeric(b)
' If both values are numeric, then do a numeric compare
If IsNum1 And IsNum2 Then
If Double.Parse(s1) > Double.Parse(s2) Then
Return 1
ElseIf Double.Parse(s1) < Double.Parse(s2) Then
Return -1
Else
Return 0
End If
' If the first value is a number, but the second is not, then assume the number is "higher in the list"
ElseIf IsNum1 And IsNum2 = False Then
Return -1
' if the first values is not a number, but the second is, then assume the number is higher
ElseIf IsNum1 = False And IsNum2 Then
Return 1
Else
' If both values are non nuermic, then do a normal string compare
Return String.Compare(s1, s2)
End If
Catch ex As Exception
Console.WriteLine(ex.ToString)
End Try
' If we got here, then we failed to compare, so return 0
return 0
End Function
Datagridview - Sorting Numeric Columns that are not bound to a DataSource
There are a lot of examples out there to sort datagridview columns that are bound to a datasource, but I could only find one example that had a solution to solving the problem of sorting when the data is not bound to a datasource.
This is the data that I have, in a csv file
Dharmit,Male,10.001,First
Lomesha,Female,11.001,Second
Jaymit,Male,7.001,Third
Ambrish,Male,8.001,First
Chanda,Female,172.00101,Second
The third column (lets call it Order) contains data that is not integers, they are double values. I load it into a datagrid view by reading each line to a String Array, and then loading the array to the datagridview.
When I do a sortascending on the Order column, it sorts it as if it was String/ or Text instead of as a number. If the Order column had values like 10, 11, 7, 8, 172 it would sort it properly, but the decimal point screws it up into thinking that it is text. The solution to this problem is to use the SortCompare event, and to manually figure out if values are equal, greater than or less than. Initially I didn't understand the sortResult values. What does 1, -1, and 0 mean. And to be honest I still don't know, just trial and error. Some things to keep in mind. The Data must not be be bound, and the VirtualMode must be False, and the SortCompare is called when the Sort is called, in my case I call it programatically and have set it such. Also the code below assumes the data is numeric.
Private Sub DataGridView1_SortCompare(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewSortCompareEventArgs) Handles DataGridView1.SortCompare
If Double.Parse(e.CellValue1) > Double.Parse(e.CellValue2) Then
e.SortResult = 1
ElseIf Double.Parse(e.CellValue1) < Double.Parse(e.CellValue2) Then
e.SortResult = -1
Else
e.SortResult = 0
End If
e.Handled = True
Exit Sub
End Sub
Thursday, April 3, 2008
MSVCR71.dll not found or MSVCP71.dll not found
My initial thought was to add the dll's to the setup application. But then I read an article that if you wanted to deploy these dll's to just add the merge module VC_User_CRT71_RTL_X86_---.msm from Program Files\Common Files\Merge Modules. So I did this. Right-click on your Setup application, select Add, then select Merge Module... and then select the module. In the properties for the file, make sure you install it in the application folder and not the setup folder. Ok, I tried this and still my application wasn't working.
So I finally decided to just add the dll's directly. Well, I right-clicked on the setup application, select Add, File. And then navigated to the Windows\System32\ directory. Found MSVCR71.dll and MSVCP71.dll (it turns out you need this one as well), and when I attempted to add them, I got a message that said that these two dll's were found in the vc_user_stl71_rtl_x86_---.msm and would I like to add that instead. So I said "Yes", then I got a message to add VC_User_CRT71_RTL_X86_---.msm, so I said ok. Installed the application on the Vista machine and everything worked fine. What ends up getting installed on the Vista machine are the dll's, not the msm files.
Anyways, the moral of the story is that if you need a dll, just go straight to it, instead of trying to figure out what msm files. The setup application is smart enough to figure out if that dll has an associated merge module. I think :-)
Monday, March 24, 2008
Implicit conversion from 'System.Array' to '1-dimensional array of Byte' in copying the value of 'ByRef' parameter 'Value' back to the matching argument
In VB6 we had the following type of code:
Dim tempBytes() As Byte, readFileHandle As Long
readFileHandle = FreeFile
Open imgFile For Binary Access Read As #readFileHandle
ReDim tempBytes(1 To LOF(readFileHandle))
Get #readFileHandle, 1, tempBytes 'dataoffset is 0-based; GET is 1-based
What this basically did was it opened an image file and then read in the image file to a byte array.
When we converted to VB2003, the code was converted and fixed as such:
Dim tempBytes() As Byte
Dim readFileHandle As Integer
readFileHandle = FreeFile()
FileOpen(readFileHandle, imgFile, OpenMode.Binary, OpenAccess.Read, OpenShare.Shared) '!!## errors?
ReDim tempBytes(LOF(readFileHandle) - 1)
FileGet(readFileHandle, tempBytes, 1) 'dataoffset is 0-based; GET is 1-based
In converting it to VB2005, I decided to turn Option Strict ON, which gave a warning on the following line. The warning is the subject of this post:
FileGet(readFileHandle, tempBytes, 1) 'dataoffset is 0-based; GET is 1-based
The warning made sense, tempBytes is type Byte, and FileGet is expecting a System.Array.
The way to fix this is to cast tempBytes as an array, and the warning will go away, and it will still work.
FileGet(readFileHandle, DirectCast(tempBytes, Array), 1) 'dataoffset is 0-based; GET is 1-based
Single Instance Applications is a lot easier in VB 2005
For more information, read the following post:
http://blogs.msdn.com/tyler_whitney/archive/2005/11/23/VB-Application-Model.aspxFrom the article:
So what's a Single-Instance application? Imagine launching an application where additional attempts to launch the app while the first one is running doesn't actually launch a new instance of the app. Instead the original instance of the app gets notified that another launch attempt occurred. When we introduced an application model for Visual Basic in VB 2005, one of the things we wanted to do is make it drop-dead easy to create single-instance applications.
Pretty much what you need to do in VB 2005 is to right click on your main project and go to properties.
then select Application, then make sure you have "Enable application framework" checked.
Then check of "Make single instance application"
For the other items. I have everything checked, and the authentication mode, I chose Windows, and the shutdown mode, I chose When startup form closes, and for the Splash screen, I have code that takes care of this.
Either way, this is a lot easier than writing code in order to make this happen properly.
-- Ted
Thursday, March 13, 2008
Integer Division in VB.NET
It pretty much talks about the difference between doing division with the "/" vs "\"
actually requires three implicit conversions, two for converting the operands from Integer to Single (to prepare them for the division) and one to convert the result from Single to Integer (to complete the assignment). If you use the "\" operator you don't incur in this overhead, and the division itself is faster. While we are on this topic, keep in mind that the "/" operator returns a Double value if at least one of its operands is a Double; therefore if you wish the highest precision when dividing two Integer or Single values, you should manually coerce one of them into Double type:
C% = A% / B%
' this prints 0.3333333
Print 1 / 3
' this prints 0,333333333333333
Print 1 / 3#
Tuesday, March 11, 2008
Using the ^ operator that can slow your application down
For example in order to square X, we did X^2. It turned out that using the "^" operator was slower than using X*X, or even using Math.Pow(X, 2). It wasn't noticeably faster if you only did this once or twice, but in our situation, we called this function millions of times, so a little improvement made a big difference.
-- Ted
Tuesday, February 26, 2008
Use PerformClick to call a Menu Item's Click event from your code
But I had an Menu Click event that I wanted to call from code. When you call Menuitem1.Click you get an error, because it expects a sender and some args. I started down the path of supplying the arguments, when I stumbled across the PerformClick event, that you can just call. Yeah.
Another option would be to move your code from the Menu Click event to another function, and call that function from both the MenuClick event and from any where else you would like to.
How to have different colors for different items in a combobox in VB.NET
http://vbcity.com/forums/faq.asp?fid=15&cat=ListBox%2FComboBox
The article shows you how to add images to combobox items and different colors. You can also download code and try things out yourself. However, for me all I wanted was to color different items a different color. Using some of the concepts from the article, this is how one can do such a thing:
1. The first thing one needs to do, in the drawmode property of the Combo Box, to select either OwnerDrawFixed, OwnerDrawVariable.
2. Next, in the DrawItem Event the user can do something the the following:
Dim g As Graphics = e.Graphics
Dim bBlue As SolidBrush = New SolidBrush(Color.Blue)
Dim bRed As SolidBrush = New SolidBrush(Color.Red)
Dim bOrange As SolidBrush = New SolidBrush(Color.Orange)
If e.Index = 0 Then
g.DrawString("Value1", Me.ComboBox1.Font, bBlue, e.Bounds.Left, e.Bounds.Top)
ElseIf e.Index = 1 Then
g.DrawString("Valu2", Me.ComboBox1.Font, bRed, e.Bounds.Left, e.Bounds.Top)
Else
g.DrawString("Value3", Me.ComboBox1.Font, bOrange, e.Bounds.Left, e.Bounds.Top)
End If
bBlue.Dispose()
bRed.Dispose()
bOrange.Dispose()
This basically colors the first value, Blue, the second value Red and everything else Orange.
Sunday, February 24, 2008
My Autos Window has Disappeared in VB.NET
Anyways, after checking MSDN library, I found that the Auto's Window can be shown and hidden by going to the Debug Menu/Window/ And selecting it from that submenu. You can also show it by pressing Ctrl+Alt+V, and then the letter A.
Friday, February 22, 2008
Beware when removing items from an ArrayList
If aList(i).Index = Index Then 'The Index was supplied to the function
aList.RemoveAt(i)
End If
Next
If aList(i).Index = Index Then 'The Index was supplied to the function
aList.RemoveAt(i)
Else
i = i + 1
End If
End While
Tuesday, February 12, 2008
How to make a form a child of a control in VB.NET
I tried doing the following:
Form1.Owner = Me.Parent
But then I had to set the Form1 as the TopMost control. And this didn't allow me to click on other parts of the control.
Anyways, the things that worked was thie following line:
Form1.TopLevel = False 'This is the key line in order to make Form1 a Child of this Control
I also do the following (which I did before):
Form1.Parent = Me
Form1.IsMdiContainer = False
Form1.BringToFront()
I no longer do the call to Form1.Owner = Me.Parent as it is not needed and having that call there messes things up.
Friday, February 8, 2008
How to completely validate input in a TextBox even on paste
The solution was to put validation logic into the TextChanged event as well. I don't remember exactly the scenario, but there might be situations where your validation logic my interpret the Ctrl-V as an invalid character, and it won't allow you to paste your values in. The way I was able to work around this was in the KeyDown event to check if the Ctrl button was pressed, if it was pressed, I would set a flag. In the KeyPress event I checked if the flag was set. If it was set, then I didn't go into my validation logic (which would have interpreted the Ctrl-V as an invalid character), I just exited the sub. This way the text was pasted, but in TextChanged, I would then validate the text that was pasted.
How to get the Short Filename to a Windows File in VB.NET
What I ended up doing was to use the Short Filename. Below is code that helped me do it. I found it on some message board, but didn't save the reference.
Private Const MAX_PATH As Integer = 260
Private Declare Auto Function GetShortPathName Lib "kernel32" ( _
ByVal lpszLongPath As String, _
ByVal lpszShortPath As System.Text.StringBuilder, _
ByVal cchBuffer As Integer) As Integer
Public Function GetShortFileName(ByVal LongPath As String) As String
Dim ShortPath As New System.Text.StringBuilder(MAX_PATH)
Dim BufferSize As Integer = GetShortPathName(LongPath, ShortPath, ShortPath.Capacity)
Return ShortPath.ToString()
End Function
Tjust call GetShortFileName with the filename you want to change and it will return the Windows Short Filename.
-- Ted
Monday, February 4, 2008
Debug Visual C++ DLL from VB.NET
Using some of the hints suggested, I was able to come up with a method that works.
I created a brand new Visual C++ dll project (called testcplusplusdll), with one cpp file (mainfile.cpp). This is what it had:
#include <windows.h>
#define CALLINGCONV __declspec(dllexport) __stdcall
int CALLINGCONV Trace() {
int hgt,wid;
hgt = 2;
wid = 2;
hgt = hgt + wid;
MessageBox(NULL,"trace1","Trace13",0);
return 1;
}
In the Project Properties. Project->testcplusplusdll Properties
Under Configuration Properties -> Debugging. For the command I entered the path to the executable of the VB.NET program (we'll get into that in a little bit). For Attach, I have the value "No", for Debugger Type, I have "Native Only" but others might work (just haven't tried it yet), everything else on that page was left to the default.
Under the Linker Folder, I kept the default settings, but they are:
under Debugging. for Generate Debug Info I have "Yes (/DEBUG)"
Generate Program Database File - "$(OutDir)/testcplusplusdll.pdb"
That's it for the C++ project. Build it, and make sure it compiles. The compiled dll ended up in a Folder called "Debug"
Now, on to the VB.NET project. I created a new Project. The location where it put the project wasn't in the same location as the C++ project. On the form, I placed a button. And Below is the code that I added to the Form.
Private Declare Function Trace Lib "..\..\testcplusplusdll\debug\testcplusplusdll.dll" Alias "?Trace@@YGHXZ" () As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Trace()
End Sub
A couple of points. To figure out the Alias of the C++ function, I used the Depends application that came with VB6. The value for Lib, is the path to the testcplusplusdll.dll that I compiled earlier.
I build the project. I am still in the Debug Configuration.
Now, I go back to my C++ project, and as I mentioned earlier, and under onfiguration Properties -> Debugging->Command, I entered the path to the executable of the VB.NET project I just built.
Now I set a beakpoint in the C++ code, and run the C++ project (it takes a while but be patient). It will popup the Form1, and when I click on Button1, it will stop in my C++ code. Yeah.
A couple of things that I read about that I tried that didn't make a difference:
1. In the VB.NET program, under Project Properties under Debugging, there is a checkbox for "Unmanaged Code Debugging", checking it or unchecking it didn't make a difference.
2. In the VB.NET, if you click on the Solution, and then go to Project->Properties. You can do "Debug Source Files" and "Debug Symbol Files". I had entered the location of the c++ source files to this location, and the location of the c++ pdb file in the Symbol Files location, but when I removed it, it didn't seem to make a difference.
Hopefully this is helpful to someone.
Sunday, January 27, 2008
CtrlV Shortcut causes a conflict with a Paste Menu Item
Now I still haven't found the perfect solution. Ideally I would like the innermost control to have precedence. So first TextEntry gets the Ctrl-V, then if we are not on the TextEntry control, the Form's mnuPaste has precedence. However, I can't seem to get this going.
The best I can do is direct the Ctrl events to the ActiveControl like this:
In the Form declare this function:
Private Declare Auto Function SendMessage Lib "user32" ( ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr ) As IntPtr
Then overide ProcessCmdKey in the Form:
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
SendMessage(Me.ActiveControl.Handle, msg.Msg, msg.WParam, msg.LParam)
End Function
You can also use this type of call to send Ctrl from the MDI Parent to the Child form. In that case you would replace Activecontrol with ActiveMdiChild.