Announcement

Collapse
No announcement yet.

couldn't display icon in tooltips

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

  • #21
    Originally posted by Stuart McLachlan View Post
    I find it very hard to believe that WIndows needs to get the application name and pass it to GetModuleHandle in order to get the handle of the instance it is creating in order to pass it to the entry point WINMAIN. Same with GetCommandLine
    Windows doesn't call WinMain (or whatever a particular programming language likes to call it). How it is going to know where to find it? It simply calls the address of the start of the code, that the loader finds using an entry in the PE header. Here, the runtime code incorporated to the application by the compiler will perform whatever it needs and call WinMain (if it exists, becuse it is not mandatory in all languages).
    Last edited by José Roca; 25 May 2020, 08:43 AM. Reason: typo correction
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #22
      https://docs.microsoft.com/en-us/win...on-entry-point

      Swinging after the bell?
      Dale

      Comment


      • #23
        To begin with, "Every Windows program includes an entry-point function that is named either WinMain or wWinMain." means every windows program written in C++. It is mandatory to have a WinMain function when using C++, but not when using other languages.

        "How does the compiler know to invoke wWinMain instead of the standard main function? What actually happens is that the Microsoft C runtime library (CRT) provides an implementation of main that calls either WinMain or wWinMain."

        That is, it is not Windows who calls WinMain, but the runtime code incorporated to the application. And as Windows does not call WinMain, but the starting address of the code, it can't pass any parameters. It is the runtime code who has to retrieve the instance handle and the command line and pass it to WinMain.
        Forum: http://www.jose.it-berater.org/smfforum/index.php

        Comment


        • #24
          The C++ runtime retrieves the command line calling the API function GetCommandLine and when calling the main function it calls GetModuleHandleA(NULL) to retrieve the instance handle...

          Code:
          StartupInfo.dwFlags = 0;
          GetStartupInfo( &StartupInfo );
          
          lpszCommandLine = _twincmdln();
          mainret = _tWinMain( GetModuleHandleA(NULL),
                               NULL,
                               lpszCommandLine,
                               StartupInfo.dwFlags & STARTF_USESHOWWINDOW
                                    ? StartupInfo.wShowWindow
                                    : SW_SHOWDEFAULT
                              );
          Code taken from crt0.c
          Forum: http://www.jose.it-berater.org/smfforum/index.php

          Comment


          • #25
            In crtlib.c, the C++ runtime retrieves both the ansi and unicode command lines, using GetCommandLineA and __crtGetCommandLineW, which is an unicode version of GetCommandLine.

            Code:
            _acmdln = (char *)GetCommandLineA();
            _wcmdln = (wchar_t *)__crtGetCommandLineW();
            Code:
            /***
            *aw_com.c - W version of GetCommandLine.
            *
            *       Copyright (c) 1994-2001, Microsoft Corporation.  All rights reserved.
            *
            *Purpose:
            *       Use GetCommandLineW if available, otherwise use A version.
            *
            *******************************************************************************/
            
            #include <cruntime.h>
            #include <internal.h>
            #include <stdlib.h>
            #include <setlocal.h>
            #include <awint.h>
            #include <dbgint.h>
            
            #define USE_W   1
            #define USE_A   2
            
            /***
            *LPWSTR __cdecl __crtGetCommandLineW - Get wide command line.
            *
            *Purpose:
            *       Internal support function. Tries to use NLS API call
            *       GetCommandLineW if available and uses GetCommandLineA
            *       if it must. If neither are available it fails and returns 0.
            *
            *Entry:
            *       VOID
            *
            *Exit:
            *       LPWSTR - pointer to environment block
            *
            *Exceptions:
            *
            *******************************************************************************/
            
            LPWSTR __cdecl __crtGetCommandLineW(
                    VOID
                    )
            {
                    static int f_use = 0;
            
                    /*
                     * Look for unstubbed 'preferred' flavor. Otherwise use available flavor.
                     * Must actually call the function to ensure it's not a stub.
                     */
            
                    if (0 == f_use)
                    {
                        if (NULL != GetCommandLineW())
                            f_use = USE_W;
            
                        else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
                            f_use = USE_A;
            
                        else
                            return 0;
                    }
            
                    /* Use "W" version */
            
                    if (USE_W == f_use)
                    {
                        return GetCommandLineW();
                    }
            
                    /* Use "A" version */
            
                    if (USE_A == f_use || f_use == 0)
                    {
                        int buff_size;
                        wchar_t *wbuffer;
                        LPSTR lpenv;
            
                        /*
                         * Convert strings and return the requested information.
                         */
            
                        lpenv = GetCommandLineA();
            
                        /* find out how big a buffer we need */
                        if ( 0 == (buff_size = MultiByteToWideChar( CP_ACP,
                                                                   MB_PRECOMPOSED,
                                                                   lpenv,
                                                                   -1,
                                                                   NULL,
                                                                   0 )) )
                            return 0;
            
                        /* allocate enough space for chars */
                        if (NULL == (wbuffer = (wchar_t *)
                            _malloc_crt(buff_size * sizeof(wchar_t))))
                            return 0;
            
                        if ( 0 == MultiByteToWideChar( CP_ACP,
                                                       MB_PRECOMPOSED,
                                                       lpenv,
                                                       -1,
                                                       wbuffer,
                                                       buff_size ) )
                            goto error_cleanup;
            
                        return (LPWSTR)wbuffer;
            
            error_cleanup:
                        _free_crt(wbuffer);
                        return 0;
                    }
                    else   /* f_use is neither USE_A nor USE_W */
                        return 0;
            }
            Fortunately, not everything is a black box like PB. There is a lot of source code available from which we can learn, instead of making wild guesses.
            Last edited by José Roca; 25 May 2020, 12:51 PM.
            Forum: http://www.jose.it-berater.org/smfforum/index.php

            Comment


            • #26
              Pardon my ignorance, what's the difference between WinMain and PBMain ?

              In what situations, do we need to use WinMain , PBMain and LibMain ?

              I knew that in a DLL we need to use LibMain.

              Comment


              • #27
                Click image for larger version

Name:	ApiMon2.PNG
Views:	95
Size:	30.0 KB
ID:	794270
                Click image for larger version

Name:	ApiMon1.PNG
Views:	51
Size:	38.6 KB
ID:	794271
                Code:
                #COMPILE EXE '#Win#
                #DIM ALL
                #REGISTER NONE
                #INCLUDE "Win32Api.inc"
                #RESOURCE MANIFEST, 1, "XPTheme.xml"
                
                GLOBAL hDlg AS DWORD
                
                $AppName  = "rohitab ApiMonitor"
                %Button01 = 101
                %Button02 = 102
                %Button03 = 103
                %Button04 = 104
                %Button05 = 105
                %Button06 = 106
                %Edit01   = 201
                '_____________________________________________________________________________
                
                CALLBACK FUNCTION DlgProc
                 LOCAL pzaCommandLine AS STRINGZ  POINTER
                 LOCAL pzwCommandLine AS WSTRINGZ POINTER
                 LOCAL Kommand        AS STRING
                 LOCAL hInstance      AS DWORD
                
                 SELECT CASE CBMSG
                
                   CASE %WM_COMMAND
                     SELECT CASE CBCTL
                
                       CASE %Button01
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                           hInstance = GetModuleHandleA("")
                         END IF
                
                       CASE %Button02
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            hInstance = GetModuleHandleW("")
                         END IF
                
                       CASE %Button03
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                           hInstance = EXE.INST
                         END IF
                
                       CASE %Button04
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            pzwCommandLine = GetCommandLineA()
                         END IF
                
                       CASE %Button05
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            pzwCommandLine = GetCommandLineW()
                         END IF
                
                       CASE %Button06
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            Kommand = COMMAND$
                         END IF
                
                     END SELECT
                
                   CASE %WM_SIZE
                     IF CBWPARAM <> %SIZE_MINIMIZED THEN
                       MoveWindow(GetDlgItem(hDlg, %Edit01), 10, 100, LO(WORD, CBLPARAM) - 20, HI(WORD, CBLPARAM) - 105, %TRUE)
                     END IF
                
                  END SELECT
                
                END FUNCTION
                '_____________________________________________________________________________
                
                FUNCTION PBMAIN()
                 LOCAL hIcon AS DWORD
                
                 DIALOG FONT "Segoe UI", 9
                 DIALOG NEW %HWND_DESKTOP, $AppName, , , 275, 200, %WS_CAPTION OR %WS_MINIMIZEBOX OR _
                 %WS_SYSMENU OR %WS_MAXIMIZEBOX OR %WS_SIZEBOX, %WS_EX_LEFT TO hDlg
                
                 hIcon = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294) 'o
                 SetClassLong(hDlg, %GCL_HICON, hIcon)
                 SetClassLong(hDlg, %GCL_HICONSM, hIcon)
                
                 CONTROL ADD BUTTON, hDlg, %Button01, "Call GetModuleHandleA", 5, 5, 100, 14
                 CONTROL ADD BUTTON, hDlg, %Button02, "Call GetModuleHandleW", 5, 20, 100, 14
                 CONTROL ADD BUTTON, hDlg, %Button03, "Get EXE.INST", 5, 35, 100, 14
                 CONTROL ADD BUTTON, hDlg, %Button04, "Call GetCommandLineA", 110, 5, 100, 14
                 CONTROL ADD BUTTON, hDlg, %Button05, "Call GetCommandLineW", 110, 20, 100, 14
                 CONTROL ADD BUTTON, hDlg, %Button06, "Get COMMAND$", 110, 35, 100, 14
                
                 CONTROL ADD TEXTBOX, hDlg, %Edit01, _
                 "Compile code." & $CRLF & _
                 "From http://www.rohitab.com/apimonitor" & $CRLF & _
                 "Download http://www.rohitab.com/download/api-monitor-v2r13-x86-x64.zip" & $CRLF & _
                 "Its portable, so, no installation needed, just unzip." & $CRLF & _
                 "" & $CRLF & _
                 "Start apimonitor-x86.exe." & $CRLF & _
                 "Click the ""Api filter"" header to give focus to this section." & $CRLF & _
                 "Type ""Ctrl-F""" & $CRLF & _
                 "Type ""GetModuleHandle"", next" & $CRLF & _
                 "Select All ""GetModuleHandle*"" items." & $CRLF & _
                 "Do the same for ""GetCommandLine""" & $CRLF & _
                 "" & $CRLF & _
                 "Now, click the ""File"" menu, ""Monitor New Process""," & $CRLF & _
                 "give the full name of the compiled exe and some argument" & $CRLF & _
                 "Enjoy..." & $CRLF, 5, 54, 205, 72, _
                 %ES_AUTOHSCROLL OR %ES_LEFT OR %ES_MULTILINE OR %ES_NOHIDESEL OR _
                 %ES_WANTRETURN OR %WS_BORDER OR %WS_TABSTOP OR %WS_VSCROLL,%WS_EX_LEFT
                
                 CONTROL SET FOCUS hDlg, %Button01
                 DIALOG SHOW MODAL hDlg CALL DlgProc
                
                 DestroyIcon(hIcon)
                
                END FUNCTION
                '_____________________________________________________________________________
                '

                Comment


                • #28
                  Tim,
                  PBMain is a function with no parameters, WinMain have some that give you the instance handle, a pointer to the command line, and the "ShowWindow" value...
                  See WINMAIN

                  Comment


                  • #29
                    Thanks Pierre, lots of learning here

                    Comment

                    Working...
                    X