Visual Basic Q&A

As a software engineer, I focus on .NET, especially asp.net, C#, WCF and so on, and I am also very interested in Search Engine Optimization.

Entries Tagged ‘project’

How To Retrieve Bitmap from Access and Display It in Web Page

Symptoms
This article shows by example how to extract the bitmap photos in theMicrosoft Access 97 Nwind.mdb database, and view them from a Webbrowser using Active Server Pages (ASP). In order to accomplish this task,an ActiveX DLL must be created that strips the Access and OLE headers fromthe field. This article shows how to create this ActiveX DLL, and how toimplement it.
Resolution
WARNING: ANY USE BY YOU OF THE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWNRISK. Microsoft provides this code “as is” without warranty of any kind,either express or implied, including but not limited to the impliedwarranties of merchantability and/or fitness for a particular purpose.
This article demonstrates how to use Visual Basic to retrieve a bitmapstored in an OLE Object field. Because the definition of OLE object storageis not documented, the following code searches the object’s OLE header forcharacters consistent with the start of the graphic. This method may notwork in all circumstances.
Be aware that Internet Explorer 3.0 is unable to display true colorbitmaps. For this reason, the bitmaps stored in the Access database shouldbe no higher than 256 colors.
Step-by-Step Example to Extract the PhotosCreate a new project in Visual Basic and make the project an ActiveXDLL.Add a reference to ActiveX Data Objects (ADO) by clicking the Projectmenu and selecting References. Select “Microsoft OLE DB ActiveX DataObjects 1.0 Library” and click OK.Add a new module to the project by selecting the Project menu andclicking Add Module. Select Module and click Open.Place the following code in the (general) (declarations) section ofMODULE1.BAS:

‘ Enter the following Declare statement as one single line:Public Declare Sub CopyMemory Lib “kernel32″ Alias “RtlMoveMemory”(lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)Type PTWidth As IntegerHeight As IntegerEnd TypeType OBJECTHEADERSignature As IntegerHeaderSize As IntegerObjectType As LongNameLen As IntegerClassLen As IntegerNameOffset As IntegerClassOFfset As IntegerObjectSize As PTOleInfo As String * 256End Type Place the following code in the (general) (declarations) section ofCLASS1.CLS:

Function DisplayBitmap(ByVal OleField As Variant)Dim Arr() As ByteDim ObjHeader As OBJECTHEADERDim Buffer As StringDim ObjectOffset As LongDim BitmapOffset As LongDim BitmapHeaderOffset As IntegerDim ArrBmp() As ByteDim i As Long’Resize the array, then fill it with’the entire contents of the fieldReDim Arr(OleField.ActualSize)Arr() = OleField.GetChunk(OleField.ActualSize)’Copy the first 19 bytes into a variable’of the OBJECTHEADER user defined type.CopyMemory ObjHeader, Arr(0), 19′Determine where the Access Header ends.ObjectOffset = ObjHeader.HeaderSize + 1′Grab enough bytes after the OLE header to get the bitmap header.Buffer = “”For i = ObjectOffset To ObjectOffset + 512Buffer = Buffer & Chr(Arr(i))Next i’Make sure the class of the object is a Paint Brush objectIf Mid(Buffer, 12, 6) = “PBrush” ThenBitmapHeaderOffset = InStr(Buffer, “BM”)If BitmapHeaderOffset > 0 Then’Calculate the beginning of the bitmapBitmapOffset = ObjectOffset + BitmapHeaderOffset – 1′Move the bitmap into its own arrayReDim ArrBmp(UBound(Arr) – BitmapOffset)CopyMemory ArrBmp(0), Arr(BitmapOffset), UBound(Arr) -BitmapOffset + 1′Return the bitmapDisplayBitmap = ArrBmpEnd IfEnd IfEnd Function Rename the Project by selecting the Project menu, and clicking on”Project1 Properties” and type your new name in the “Project Name”field. This example assumes that you named the project “MyProject” andwill refer to that name in future steps.Select the”Unattended Execution” check box. Click OK.Rename the Class in the Property Pane. This example assumes that younamed the class “MyClass” and refers to that name in future steps.Compile the DLL by clicking the File menu and selecting “MakeMyProject.dll.”Create an ASP page named “bitmap.asp” that contains thefollowing code:

<%@ LANGUAGE=”VBSCRIPT” %><%’You need to set up a System DSN named ‘NWind’ that points to’the Northwind.mdb databaseSet DataConn = Server.CreateObject(“ADODB.Connection”)DataConn.Open “DSN=NWind”, “admin”, “”Set cmdTemp = Server.CreateObject(“ADODB.Command”)Set RS = Server.CreateObject(“ADODB.Recordset”)cmdTemp.CommandText = “SELECT Photo FROM EmployeesWHERE EmployeeID = 1″cmdTemp.CommandType = 1Set cmdTemp.ActiveConnection = DataConnRS.Open cmdTemp, , 0, 1Response.ContentType = “image/bmp”Set Bitmap = Server.CreateObject(“MyProject.MyClass”)Response.BinaryWrite Bitmap.DisplayBitmap(RS(“Photo”))RS.Close%> Create an HTML page named “BitmapTest.htm” that containsthe following code:

<HTML><HEAD><TITLE>Bitmap Test</TITLE></HEAD><BODY><HR><img src=”Bitmap.asp”><HR></BODY></HTML>

How To Create a DCOM Client/Server Application by Using Visual Basic

Symptoms
This article shows you how to create, package, and deploy a Distributed Component Object Model (DCOM) client/server application by using Visual Basic. To create a DCOM client/server application, you need the Enterprise Edition of Visual Basic. Microsoft assumes that the reader is already familiar with creating client/server applications that run on the same computer.
Resolution
You do not need to change your code to enable a client application to instantiate a remote server by using DCOM. The difference is the way in which you package and deploy the client. In addition, there are some security settings you need to make after the client and the server are installed. You can make these settings by using an utility called Dcomcnfg.
The following steps show you how to distribute and configure a simple client/server application. Name the server DCOMDemo_Svr, and name the client DCOMDemo_Cli. Create a separate folder for each of them. For the purpose of this article, call these folders c:\DCOMDemo\Server and c:\DCOMDemo\Client.
Create the ServerStart a new Visual Basic Project. On the New Project dialog box, select ActiveX EXE, and then click Open. Class1 is created by default. Add the following code to the Class1 module:

Public Function ServerTime() As StringServerTime = TimeEnd Function On the Project menu, click the Project Properties option, and then select the General tab.In the Project Name field, type in DCOMDemo_Svr.On the Project Description field, type in DCOMDemo_Svr – Server. Check the Unattended Execution option.
NOTE: This option should always be checked in servers that don’t have any UI to assure that no dialog boxes of any type are displayed while the server is running. If you have any type of user interaction while your server is running under an identity that is not the Interactive User, your server may appear to hang.Select the Component tab, and check the Remote Server Files option.
NOTE: Checking this option makes the Visual Basic compiler generate the VBR and TLB files needed for packaging the client applications that use this server. These files contain registry entries that need to be included on the client computer.Close the Project Properties dialog box.On the File menu, select Save As, and then save this project to the c:\DCOMDemo\Server folder.On the File menu, select Make DCOMDemo_Svr and compile the server.On the Project menu, select the Project Properties option, and then select the Component tab.On the Component tab, select Version Compatibility, select the Binary Compatibility option, and then make the project binary compatible with the server’s executable file you just created (DCOMDemo_Svr.exe). By selecting this option you are assuring that all GUIDs are kept the same if you recompile the server.
Create the ClientOn the File menu, select the New Project option, select Standard EXE, and then click OK. Form1 is created by default.On the Project menu, click the Project Properties option, and then select the General tab.In the Project Name field, type in DCOMDemo_Cli. In the Project Description field, type in DCOMDemo_Cli Project – Client.On the Project menu, select References. From the list of available references, select DCOMDemo_Svr – Server. Place a command button on Form1, and change the button’s caption to Run.Place the following code in the button’s click event:

Dim MyObj As DCOMDemo_Svr.Class1On Error GoTo err1Set MyObj = CreateObject(“DCOMDemo_Svr.Class1″)MsgBox “Server Time=” & MyObj.ServerTime & “Client Time=” & TimeExit Suberr1:MsgBox “Connection failed: Error ” & Err.Number & ” – ” & Err.Description On the File menu, select Save As, and then save the project to the client’s folder c:\DCOMDemo\Client. Press the F5 key to run the client in the IDE and test it out.On the File menu, select Make DCOMDemo_Cli to compile the client, and then close Visual Basic.
Package the ServerUse the Package and Deployment Wizard to package your server for distribution as usual. The server is instantiated by a remote client using DCOM. While creating the package for your server, you get a dialog box asking you if this server will be used as a Remote Automation server and if you want to include support files for this purpose. Just click the No button, because DCOM is not Remote Automation. Remote Automation is an older technology that was replaced by DCOM.
Package the ClientWhen packaging the client there are some specific steps that need to be taken, considering that the server does not run on the same computer as the client. The changes made to the client’s package assure that just the type library (.tlb file) is installed and some additional registry entries are included instead of the server’s executable, which is not necessary on the client’s computer because it’s not going to run there.
Package the client by using the following steps:Start Package and Deployment Wizard, and then select the Client’s project.Click the Package button. In the Package Type dialog box, select Standard Setup Package, and then click Next.In the Package Folder dialog box, select the folder to store the package, and then click Next. In this case, it is c:\DCOMDemo\Client\Package.
NOTE: You may get a dialog box saying that there is no dependency information for the server. Click OK because this server doesn’t have any dependencies.
You should now be in the Included Files dialog box. Deselect the server’s executable file, DCOMDemo_Svr.exe, because you do note want to distribute the server’s executable, and then click the Add button. Change the Files of Type combo box to Remote Server Files (*.vbr).Point to the folder where you have your Server’s project (in this case c:\DCOMDemo\Server), and select the related VBR file, DCOMDemo_Svr.VBR. Click Open, and the Add File dialog box closes. Notice that two files are included, DCOMDemo_Svr.VBR and DCOMDemo_Svr.TLB. Click the Next button.
NOTE: In the Remote Servers dialog box you can define the name of the computer (Net Address) where the server is running. Usually you keep this field blank because you may not know in advance where the server will be installed. If you keep it blank, you are prompted for it when you install the client. For this sample, keep it blank.Click Next to proceed. You can now proceed with the standard procedures for Package and Deployment Wizard. In this case, just click Next to all remaining dialog boxes
Install the ServerInstall the server on the computer on which you would like to run it, using the distribution package you created earlier. If you want to use your development computer to run the server, you don’t need to install it because Visual Basic makes the registration for you when it compiles the server.
Install the ClientInstall the Client on the computer on which you would like to run it, using the distribution package you created earlier. Because this client uses a DCOM server and you left the actual location of the server blank when you created the distribution package, you now need to provide this location. When Setup prompts you for this location, provide the name of the computer where you installed the server.
Set the Server’s SecurityIf you installed the server on a Microsoft Windows NT or Microsoft Windows 2000 computer, you need to configure security for it. Do this by using Dcomcnfg, as shown in the following steps, which assume that both client and server computers are part of a domain, and the user logged on to the client computer is logged on as a domain user. The suggested settings are just one possible configuration. They are very generic and give wide access to the server. Remember that this is just an example. When you deploy your real applications, and security is a concern for your environment, you should select more restrictive options. Also, if the computer you are using to test this example server is used to run other servers, make a note of the current settings before you make the following changes, and return to the original settings as soon as you are done with your tests.On the server computer, click the Start button, and then select Run. In the Run dialog box, type Dcomcnfg, and then click OK. You need to have Administrator rights to be able to run Dcomcnfg.Select the Default Properties tab, and verify that Enable Distributed COM on this computer is checked.Set the Default Authentication Level to Connect, and set the Default Impersonation Level to Identify.Select the Default Security tab.Click the Edit Default button in the Default Access Permissions panel.Verify that Everyone and System are included in the list with Allow Access rights. If they are not, you can use the Add button to add them to the list. Click OK when the list is complete.Click the Edit Default button in the Default Launch Permissions panel.Verify that Everyone and System are included in the list with Allow Launch permissions. If they are not, use the Add button to add them to the list. Click OK when the list is complete.Select the Applications tab, highlight your server, DCOMDemo_Svr.Class1, and then click the Properties button. Select the General tab, set the Authentication Level to Default, and then select the Location tab.The only option that is checked should be Run application on this computer.Select the Security tab and verify that the Use default access permissions and the Use default launch permissions options are checked.Select the Identity tab, check The launching user option, click OK to close the Server’s Properties dialog box, and then click OK again to close Dcomcnfg.As you can see, the test server uses all of the default settings. When deploying your own servers, you should define settings specific to your application. All custom settings take precedence over the default ones.
You are now ready to test your server. On the client computer, launch the client, and then click the Run button. You should see a message box indicating the server’s time. If you are unable to test this sample successfully, please see the troubleshooting article, Q269330, listed in the “References” section.

FIX: VSS integration slow updating source code control status

Symptoms
When you use Visual SourceSafe integration with Visual C++, you may experience significant performance loss under the following conditions:
Two or more users execute a source control operation that results in refreshing the file status at the same time.And, the project contains a high percentage of deleted files in the Visual SourceSafe project.And, the project is more than one project away from the root project. Performance loss can occur in other applications, such as Visual Basic, Visual FoxPro, Visual J++, Visual Studio, Visual Modeler, and Microsoft Access when using integration with Visual SourceSafe.
Resolution
The performance problem is a result of the inefficient file access behavior in Visual SourceSafe.

FIX: Visual Basic .NET 2002 Upgrade Wizard stops responding with a project containing a UserControl

Symptoms
When you attempt to upgrade a Microsoft Visual Basic 6 project to Visual Basic .NET, and the project contains a UserControl, the Upgrade Wizard may stop responding (hang) or throw an exception.
Specifically, when you perform the upgrade on a Microsoft Windows XP-based computer, the Upgrade Wizard may stop responding. When you upgrade on a Microsoft Windows 2000-based computer, you may receive the following error message:

The exception unknown software exception (0×00000fd) occurred in the application at location 0×20078c3e NOTE: The Visual Basic .NET Upgrade Wizard is included in Visual Studio .NET Professional.
Resolution
This behavior can occur if an instance of the UserControl cited on a form has the same name as the project.

FIX: AddConfiguration Method Fails for Makefile Projects

Symptoms
The AddConfiguration automation method fails with the following error when called from a Developer Studio macro and the active project is a makefile project:

The configuration could not be added to the project.
Resolution
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.
This bug was corrected in Visual Studio 6.0 Service Pack 3. For more information about Visual Studio service packs, please see the following articles in the Microsoft Knowledge Base:
194022 INFO: Visual Studio 6.0 Service Packs, What, Where, Why?(http://support.microsoft.com/kb/194022/EN-US/)
194295 HOWTO: Tell That Visual Studio 6.0 Service Packs Are Installed?(http://support.microsoft.com/kb/194295/EN-US/)

BUG: You receive a “Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall” error message when you make a late-bound call in Visual Basic .NET

Symptoms
When you make a late-bound call in Microsoft Visual Basic .NET, the late-binding support fails when the ByRef decimal is converted to ByRef currency. You receive the following error message:

Unhandled Exception: System.Runtime.InteropServices.COMException (0×80020005): Type mismatch. at Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack, Boolean IgnoreReturn) at Microsoft.VisualBasic.CompilerServices.LateBinding.LateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack) at ConsoleApplication2.Module1.main() in C:\ConsoleApplication\Module.vb:line number
Press any key to continueNote In this error message, C:\ConsoleApplication\Module.vb:line number is a placeholder for the actual path where the application is saved. In the application module, line number represents the line where the error occurs.
Resolution
To work around this bug, use either of the following options: Use the CurrencyWrapper type.Force the decimal value to be passed by using the ByVal keyword.
To do this, put parentheses around the variable that contains the decimal value.To implement either of these workaround options, create a DLL by using Visual Basic 6.0, create a console application, and reference the DLL in the console application, as follows:Create a DLL by using Visual Basic 6.0Start Visual Basic 6.0.On the File menu, click New Project.
The New Project dialog box appears.Click ActiveX DLL, and then click OK.
By default, the Class1 class is created.Add the following code to the Class1 class:

Public Function cedrbank(name As String, ACCNUM As String, ACCBAL As Currency) As LongMsgBox ACCBALACCBAL = 4.321End FunctionOn the File menu, click Save Class1.cls, and then click Save Project As.In the File name box, type the name of the project.On the File menu, click Make Project.dll.
The Make Project dialog box appears.
Note Project is a placeholder for the actual name of the project.Click OK.Create a console applicationStart Visual Studio .NET.On the File menu, point to New, and then click Project.
The New Project dialog box appears.Under Project Types, click Visual Basic Projects.Under Templates, click Console Application.Click OK.
By default, the Module1.vb module is created.Replace the existing code in the Module1.vb module with the following code:

Imports SystemImports System.Runtime.InteropServicesImports System.ReflectionImports Project1Public Module Module1Sub Main()Dim x As Objectx = New Class1Dim dc As Object = New CurrencyWrapper(5)Dim d As Decimal = 1.987Dim args(2) As Objectargs(0) = “name”args(1) = “num”args(2) = dcDim c(0) As Reflection.ParameterModifierc(0) = New Reflection.ParameterModifier(3)c(0).Item(0) = Truec(0).Item(1) = Truec(0).Item(2) = TrueCObj(x).GetType().InvokeMember(“cedrbank”, BindingFlags.InvokeMethod, Nothing, x, args, c, Nothing, Nothing)Console.WriteLine(args(2))dc = New CurrencyWrapper(6)’Use the CurrencyWrapper type.x.cedrbank(“name”, “num”, dc)Console.WriteLine(dc)’Force ‘d’ to be passed ByVal by using parentheses around ‘d.’x.cedrbank(“name”, “num”, (d))Console.WriteLine(d)End SubEnd ModuleAdd a reference to the DLL that you created in the “Create a DLL by using Visual Basic 6.0″ section of this article.On the Build menu, click Build Solution.On the Debug menu, click Start.
You do not receive the error message that is mentioned in the “Symptoms” section of this article.