Bristle Software Windows Programmer Tips

This page is offered as a service of Bristle Software, Inc.  New tips are sent to an associated mailing list when they are posted here.  Please send comments, corrections, any tips you'd like to contribute, or requests to be added to the mailing list, to tips@bristle.com.

Table of Contents:

  1. Control Tips
    1. TextBox Tips
      1. Undo support for TextBox control
      2. Managing lines and text in a TextBox control
  2. DLL Tips
    1. Moving an OLE DLL with Explorer
    2. Installing a system DLL
    3. Loading a local copy of a DLL
    4. Checking which DLLs are loaded
    5. Checking which DLLs are required
  3. Visual Studio Tips
    1. Word Completion

Details of Tips:

  1. Control Tips

    1. TextBox Tips

      1. Undo support for TextBox control

        Last Updated: 12/19/1998
        Applies to:  Win 3.1?, Win95, WinNT 3.51? WinNT 4.0

        The Windows TextBox control has native support for Undo and a dirty flag.

        The Jan 1999 issue of VBPJ has a short article about how to access the native capabilities of Windows controls from VB via SendMessage. It shows how to use the following messages to take advantage of the native undo capability and the native dirty flag of the Windows TextBox:
            - EM_UNDO (undo last edit since undo buffer was emptied)
            - EM_GETMODIFY (get dirty flag)
            - EM_SETMODIFY (clear dirty flag)
            - EM_EMPTYUNDOBUFFER

        For details, see:

            http://www.vbpj.com/upload/free/features/vbpj/1999/jan99/hm0199/hm0199.asp

        --Fred

      2. Managing lines and text in a TextBox control

        Last Updated: 12/19/1998
        Applies to:  Win 3.1?, Win95, WinNT 3.51? WinNT 4.0

        To search for text in a TextBox and to manipulate the lines of text, send the following Windows messages to the TextBox via SendMessage:
            - EM_FINDTEXT (find text; get index into string)
            - EM_LINEFROMCHAR (get line from index)
            - EM_GETFIRSTVISIBLELINE (is line visible?)
            - EM_LINESCROLL (scroll line to be visible)
            - EM_GETLINECOUNT (how many lines?)
            - EM_GETLINE (get nth line of text)
            - etc.

        For details, see:

            http://www.vbpj.com/upload/free/features/vbpj/1999/jan99/hm0199/hm0199.asp

        --Fred

  2. DLL Tips

    1. Moving an OLE DLL with Explorer

      Last Updated: 2/6/2000
      Applies to:  Win95?, Win98?, WinNT 4.0

      Moving an OLE DLL via Windows Explorer does more than just move the file.  It also updates references in the Windows Registry to refer to the new location.

      This is a useful feature if you are a "dumb user" who doesn't know what he is doing.  It keeps you from accidentally disabling applications that use the DLL.

      However, it can be very misleading if you are a developer, purposely moving the DLL out of the way as part of an experiment or to temporarily use a different copy.  You may draw incorrect conclusions believing that you are using the new copy, when in fact, you are still using the old one.

      Moving the DLL via the command line doesn't have the same "helpful" side effect.

      --Fred

    2. Installing a system DLL

      Last Updated: 2/6/2000
      Applies to:  Win2000

      Windows 2000 has a new feature ("Windows File Protection") that is intended to make it harder for an install of a new application to break previously installed applications.   However, I think Microsoft made a mistake here.  They are solving a complex problem with an even more complex solution.

      Here's how it works.  Certain system DLLs (approximately 2800 of them) are marked as "protected".  Any attempt to overwrite them, except by a Windows Service Pack, fails.  So far, so good.  The part I don't like is that the copy appears to succeed.  No error code is returned to the install program.  No message is displayed to the user.  This is very misleading.  I prefer a simpler world where a command either does what it is supposed to, or returns an error message.  I think this is a step in a dangerous direction.

      For more details, see:

          http://msdn.microsoft.com/library/default.asp?URL=/library/techart/dlldanger1.htm

      --Fred

    3. Loading a local copy of a DLL

      Last Updated: 2/20/2000
      Applies to:  Win95, Win98, WinNT 3.51, WinNT 4.0

      What to do if one application (App1.EXE) requires a specific version of a shared DLL, but other applications on the same machine require a different version?

      One technique is to keep a copy of the required version of the DLL in the same directory as App1.EXE.  When Windows loads a DLL, it looks in the following sequence of locations:

      1. The directory from which the application loaded.
      2. The current directory.
      3. The Windows system directory.
      4. The Windows directory.
      5. The directories that are listed in the PATH environment variable.

      Thus, each EXE can have its own copy of the DLL. 

      For details, see the documentation for the LoadLibrary API:

          http://msdn.microsoft.com/isapi/msdnlib.idc?theURL=/library/psdk/winbase/dll_1o8p.htm

      Unfortunately, this techinique applies only to regular Windows DLLs, not COM DLLs.   Regular DLLs are found based on the DLL filename via the sequence shown above.   COM DLLs are found via the ProgId or GUID of the object requested by the EXE.   The ProgId or GUID is found in the Windows Registry, where it specifies the exact location for the DLL.

      Thanks to Glenn Frantz, Mike Brocious, and Howard Kapustein for catching an error in my original version of this tip.

      --Fred

    4. Checking which DLLs are loaded

      Last Updated: 11/28/2000
      Applies to:  Win95, Win98, WinNT 3.51, WinNT 4.0, Win2K

      To determine which DLLs are currently loaded into memory, use the "Microsoft System Information" utility.

      You won't find it in your Start Menu by default, but you can still run it.  Search for MSINFO32.EXE on your disk.  It is probably in some location like:
          \Program Files\Common Files\Microsoft Shared\MSInfo.
      Alternatively, you can run it via the "System Info..." button in the About box of some Microsoft Office apps (Word, Excel, Power Point, etc.).

      In the tree view on the left, select "Active Modules" to get a complete list of all loaded DLLs, including the full path of the DLL's filename.

      Very useful for determining whether a certain DLL is being loaded from the file you expect.

      Feedback:

      1. Adrienne Kerbel points out that it works for Win2K also, but in that version it's "Software Environment | Loaded Modules", not "Active Modules".
      2. Joe McPeak also recommends the freeware utility HandleEx from http://www.sysinternals.com (a great site -- you should check it out!)

      --Fred

    5. Checking which DLLs are required

      Last Updated: 11/26/2000
      Applies to:  Win95, Win98, WinNT 3.51, WinNT 4.0

      To determine which DLLs are required by an application, use the Microsoft "Dependency Walker" (DEPENDS.EXE), "QuickView" (QUIKVIEW.EXE), or DUMPBIN.EXE utilities.

      You won't find any of these in your Start Menu by default, but you can still run them if they are installed on your system.  Search for them on your disk.

      1. DEPENDS.EXE is shipped with various Visual Studio tools, and is likely to reside in the COMMON\TOOLS subdirectory of the directory where Visual Studio is installed.  It is also available for download at:
            http://www.microsoft.com/MSJ/code/depends.htm
        It shows the dependencies of an EXE or DLL file on various DLL's and those DLL's on each other in a graphical tree view.
      2. QUIKVIEW.EXE is shipped with Windows 95, 98, NT, etc., and is likely to reside in the directory:
           \WINDOWS\SYSTEM\VIEWERS
        or
           \WINNT\SYSTEM32\VIEWERS
        It shows a textual description of the EXE or DLL, including an "Import Table" section that shows the dependency of the EXE or DLL on various DLL's, but not the dependencies of those DLL's on each other (one level of dependencies only).
      3. DUMPBIN.EXE is shipped with Visual C++, and is likely to reside in the BIN subdirectory of the directory where Visual C++ is installed.  When this command line utility is invoked with the /IMPORTS option, it shows the dependency of the EXE or DLL on various DLL's, but not the dependencies of those DLL's on each other (one level of dependencies only).

      Note that all of these utilities have the same limitation.  They only report the dependencies created via an "import library" -- those that are resolved implicitly at runtime.  They do not report dependencies on DLLs that are loaded explicitly by the calling EXE or DLL via the Windows LoadLibrary API.  Unfortunately, almost all dependencies of an EXE or DLL written in Visual Basic are resolved explicitly via LoadLibrary calls.  The VB Runtime system explicitly calls LoadLibrary for each DLL mentioned in the VB Project (VBP) file or in a VB Declare statement.   Therefore, these tools are all pretty useless with EXEs and DLLs written in VB.

      For more information, see:
          http://support.microsoft.com/support/kb/articles/Q178/4/89.ASP
      but note that the description of DUMPBIN.EXE refers incorrectly to the /IMPORT option -- should be /IMPORTS.

      --Fred

  3. Visual Studio Tips

    1. Word Completion

      Last Updated: 3/12/2000
      Applies to:  VB5+, VS 6+

      You can't help but have noticed the helpful popups in recent versions of the Visual Studio IDEs.  The "IntelliSense" features now exist not only in VB, but all of the IDEs (VB, VC++, VJ++, VID, etc.).  The features include:

      1. List Members
        When you type a period after the object variable name, it pops up a list of the members (properties and methods) of the object.
      2. List Constants
        When you are about to enter a parameter of an enumerated type or assign a value to a variable of an enumerated type, it pops up a list of the enumerated values.
      3. Parameter Info
        When you enter the opening parenthesis of a subroutine call, it pops up a list of argument names and types.

      These features are hard to miss because they pop up all the time, without you having to do anything special.  However, you may have missed another useful IntelliSense feature that doesn't happen automatically:

      1. Word Completion
        After typing 0 or more letters of an identifier, you can hit Ctrl-Space to see a popup list of possible completions of the identifier.  If you've typed 0 letters, this is a way to see all of the available variables, functions, procedures, objects, etc.  If you've typed a partial name with multiple possible matches, you can choose the desired completion from a list.  If you've typed enough to uniquely identify one name, that name is completed.  Very handy if you use long detailed variable names! 

      BTW, you can also explicitly invoke the other 3 IntelliSense features, but the keys to do so differ in each IDE.  See the Edit menu of each IDE for details.  These can be handy if you have already dismissed the popup by hitting Escape or have selected the wrong item from the list.  However, I usually find it just as easy to back up a few chars and re-type the triggering char (period, parenthesis, etc.)

      Related Tips:  Windows NT offers a similar capability for completing filenames.   See Windows Command Line Completion for details.

      --Fred

©Copyright 1998-2021, Bristle Software, Inc.  All rights reserved