Announcement

Collapse
No announcement yet.

Change EXE icon

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Change EXE icon

    I have a program that has to show a different icon depending of the platform.

    I do not want to compile 5 different versions.

    Here is my idea.

    I am creating a res file with the 5 different icons

    BW98 ICON "...."
    BWME ICON ".... "
    BWNT ICOB "...."
    BW2K ICON "...."
    BWXP ICON "...."

    If I want to show the icon for Win Me then I can have my installer program to
    edit the exe file and find BWME and rename it to AWME, this will make the EXe use
    this icon for the EXE.

    The problem is that I cannot find the STRING "BWME" because I think is in UNICODE FORMAT.

    If I use a unicode editor I am able to see the string "BWME"

    Can someone help me with this?

    Thanks in advance,

    ------------------
    Pedro Camargo
    Pedro Camargo

  • #2
    Pedro,

    I would be looking at an API call like GetVersionEx() to determine
    the OS version and depending on the results, you select which Icon
    to display when you use LoadIcon().

    I have used GetVersionEx() on win95 and it works OK, tells you the
    difference between NT etc ... but you will need to know the data
    from each version to look for.

    Regards,

    [email protected]

    ------------------
    hutch at movsd dot com
    The MASM Forum

    www.masm32.com

    Comment


    • #3
      Pedro--
      Actually to "patch" an Exe is not difficult.

      Each ICO file includes one or some icons (for Exe is better to use ICO with 3 icons - 16 * 16, 32 * 32, 48 * 48 * 8bpp).

      You can place ICO-files (as RCDATA) into installer and to compile main exe with one of this ICO.

      During installation read required ICO as "file" and choose images of icons.
      Let's say that you read ICO-file into string variable s.
      First six bytes of this string will be ICONDIR structure.
      Code:
         Type ICONDIR
            idReserved As Word ' // Reserved (must be 0)
            idType  As Word    ' // Resource Type (1 For icons)
            idCount As Word    ' // How many images?
         End Type
      Then idCount nomber of ICONDIRENTRY
      Code:
         Type ICONDIRENTRY
            bWidth As Byte         ' // Width, In Pixels, of the Image
            bHeight As Byte        ' // Height, In Pixels, of the Image
            bColorCount As Byte    ' // Number of colors In Image (0 If >=8bpp)
            bReserved As Byte      ' // Reserved ( must be 0)
            wPlanes As Word        ' // Color Planes
            wBitCount As Word      ' // Bits per pixel
            dwBytesInRes As Dword  ' // How many bytes In this resource?
            dwImageOffset As Dword ' // Where In the file is this image?
         End Type
      Using dwBytesInRes and dwImageOffset you can extract from s all images, let's say, into string variables s1$, s2$, s3$.

      Do the same procedure with "master" ICO (which was used in main Exe) and retrieve t1$, t2$, t3$.

      Now open main exe, search t1$ and replace it by s1$, t2$ by s2$, t3$ by s3$.

      ------------------
      E-MAIL: [email protected]

      Comment


      • #4
        Semen:

        I was already trying to do that.

        But I am having problems extracting the images from the files, I will only have one icon per platform.

        Actually, I have more experience with networking and databases and this is getting me crazy.

        I was checking the forums and saw that you have a pbcc code that does this.

        Would you mind posting the code in the source forum or emailing ut to me. Please.

        I have been working on this for the last 3 days and I am not been able to find the solution.


        Thanks

        ------------------
        Pedro Camargo
        Pedro Camargo

        Comment


        • #5
          Pb/CC is enough large and is able to confuse.
          Well, I made a sample.
          Take any icon (in sample Excel.Ico).
          Include it into resource file.

          Following code searches icon's imaging inside Exe, using "row" original ico-file.

          Code:
             #Compile Exe
             #Dim All
             #Register None
             #Include "Win32Api.Inc"
             #Resource "~Tmp.pbr"
             
             '% PROGRAM  ICON Excel.Ico
             
             $FileIco = "excel.ico" ' <-- Change
          
             Type ICONDIR
                idReserved As Word ' // Reserved (must be 0)
                idType  As Word    ' // Resource Type (1 For icons)
                idCount As Word    ' // How many images?
             End Type
          
             Type ICONDIRENTRY
                bWidth As Byte         ' // Width, In Pixels, of the Image
                bHeight As Byte        ' // Height, In Pixels, of the Image
                bColorCount As Byte    ' // Number of colors In Image (0 If >=8bpp)
                bReserved As Byte      ' // Reserved ( must be 0)
                wPlanes As Word        ' // Color Planes
                wBitCount As Word      ' // Bits per pixel
                dwBytesInRes As Dword  ' // How many bytes In this resource?
                dwImageOffset As Dword ' // Where In the file is this image?
             End Type
          
          
             Function PbMain
                ' Read Exe
                Dim TmpAsciiz As Asciiz * %MAX_PATH, sExe As String
                GetModuleFileName GetModuleHandle(""), TmpAsciiz, SizeOf(TmpAsciiz)
                Open TmpAsciiz For Binary Shared As #1: Get$ #1, Lof(1), sExe: Close #1
          
                ' Read original ico-file
                Dim sIco As String, i As Long
                Open $FileIco For Binary Shared As #1: Get$ #1, Lof(1), sIco: Close #1
          
                ' Find icons inside Exe
                Dim pIconDir As ICONDIR Ptr
                pIconDir = StrPtr(sIco)
                ReDim IconDirEntry(1 To @pIconDir.idCount) As ICONDIRENTRY At pIconDir + SizeOf(@pIcondir)
                
                Dim ssIco As String
                
                For i = 1 To @pIconDir.idCount
                   ssIco  = Mid$(sIco, IconDirEntry(i).dwImageOffset + 1, IconDirEntry(i).dwBytesInRes)
                   MsgBox Str$(IconDirEntry(i).bWidth) + " *" + Str$(IconDirEntry(i).bHeight) + " : Mid$(sExe, " + _
                      Str$(Instr(-1, sExe, ssIco)) + "," + Str$(IconDirEntry(i).dwBytesInRes) + ")"
                Next
             End Function
          ------------------
          E-MAIL: [email protected]

          Comment


          • #6
            Pedro --

            > show a different icon depending of the platform.

            Are you trying to affect the icon that is shown in the title bar when your program is run, or the icon that is shown in Microsoft Explorer next to the file name, or both?

            If you are trying to affect the title bar icon, then no file-patching is necessary. Simply have your program detect the Windows version at runtime, and use runtime code to change the title bar icon. Search this BBS for WM_SETICON and you will find many examples. (If you are using PB/CC it is somewhat more difficult, but not much.)

            If you are trying to affect the icon that is shown by Explorer (or on the Windows desktop, etc.) have you considered what will happen if your program is installed on a network? For example, my office network is based on Windows NT4, but we have workstations of all types connected to the network. Windows 95, 98, ME, NT4, and 2000. If you patch the icon in the EXE file to match the Windows version of the workstation or the server, it would show the wrong icon on many different workstations in our office. (This may or may not be an issue for you, but I thought I should mention it.)

            -- Eric


            ------------------
            Perfect Sync Development Tools
            Perfect Sync Web Site
            Contact Us: mailto:[email protected][email protected]</A>
            "Not my circus, not my monkeys."

            Comment


            • #7
              Semen:

              I got it working with your code, but it requires for the icons to have the same size.

              I do not know how to make them of the same size.

              How about replacing the whole resource, I am only using the resource file for the icon.

              I really apreciate your assistance,

              ------------------
              Pedro Camargo
              Pedro Camargo

              Comment


              • #8
                Pedro --
                > it working with your code, but it requires for the icons to have the same size.
                > I do not know how to make them of the same size.

                It's necessary special efforts to make icons with different size.
                Many icon editors simply are not able to produce icons with different sizes.

                Download shareware MicroAngelo and make all icons 32 * 32 (256 colors).

                > How about replacing the whole resource, I am only using the resource file for the icon.

                RSRC does this work fine. But I don't see reasons to use it in this case.

                ------------------
                E-MAIL: [email protected]

                Comment


                • #9
                  Semen:

                  Thanks for your help, I created an big icon in the main exe with all black pixes and when I replace the icon
                  I just fill out the differennce with chr$(0) and now is working fine.

                  I could not have been done this without your help,

                  Thank you, thank you, thank you.



                  ------------------
                  Pedro Camargo
                  Pedro Camargo

                  Comment

                  Working...
                  X