Конференция "WinAPI" » ProcessID и иконка родительской консольной программы
 
  • Тыщ (24.04.08 23:56) [0]
    Есть консольная программа.
    Нужно при запуске второй консольной программы из нее узнать ProcessID первой консольной программы.
    Вторая программа использует то же окно, что и первая.

    К чему это все:

    При запуске моей консольной программы, я пытаюсь изменить иконку консоли, а при завершении восстановить старую иконку.
    Не получается. После завершения на панели задач остается иконка второй программы, а в заголовке окна и в Alt+Tab - иконка CMD.
    Такое происходит тогда, когда Handle иконки неверный, то есть иконка CMD - иконка по умолчанию.

    var
     OldIconBig,OldIconSmall:HICON;

    procedure SaveConsoleIcon;
    begin
     If not User32Loaded then Exit;
     OldIconBig:=HICON(PostMessage(GetConsoleWindow,WM_GETICON,ICON_BIG,0));
     OldIconSmall:=HICON(PostMessage(GetConsoleWindow,WM_GETICON,ICON_SMALL,0));
    end;

    procedure SetConsoleIcon;
    begin
     If not User32Loaded then Exit;
     PostMessage(GetConsoleWindow,WM_SETICON,ICON_BIG,
       LoadIcon(GetModuleHandle(nil),MakeIntResource(1)) );
     PostMessage(GetConsoleWindow,WM_SETICON,ICON_SMALL,
       LoadImage(GetModuleHandle(nil),MakeIntResource(1),IMAGE_ICON,16,16,LR_SHARED) );
    end;

    procedure RestoreConsoleIcon;
    begin
     If not User32Loaded then Exit;
     PostMessage(GetConsoleWindow,WM_SETICON,ICON_BIG,OldIconBig);
     PostMessage(GetConsoleWindow,WM_SETICON,ICON_SMALL,OldIconSmall);
    end;



    Подозреваю, что старую иконку надо получать другим образом, поэтому спрашиваю про ProcessID.
  • Сергей М. © (25.04.08 08:43) [1]
    http://forum.sources.ru/index.php?showtopic=209024


    > If not User32Loaded then Exit


    А это что за танцы с бубном ?
    С какого перепугу User32 может быть не Loaded, если он статически прописан в таблице импорта ?
  • Тыщ (25.04.08 10:32) [2]
    Сергей М. ©   (25.04.08 8:43) [1]

    Спасибо.
    Хм... Перепробовал я варианты с ProcessID - не получается иконку из чужого процесса достать.
    Если искать окно, то приходим к тому же GetConsoleWindow, и WM_GETICON с ним не работает.

    Есть идея разве что лезть в exe-шник родительского процесса и доставать из него иконку...
    Но не факт, что именно первая иконка (или какую достанем) поставлена у консольного окна, так что вариант не ахти.

    Есть еще идеи, как достать иконку?
    Может, я просто что-то упустил в SaveConsoleIcon? [0]

    > С какого перепугу User32 может быть не Loaded, если он статически прописан в таблице импорта ?

    У меня - динамически. Прикол такой. Долго рассказывать, не обращайте внимания. :)
  • DVM © (25.04.08 13:27) [3]

    > Если искать окно, то приходим к тому же GetConsoleWindow,
    >  и WM_GETICON с ним не работает.

    а так:


    HICON GetWindowIcon(
       __in HWND hWnd
       )
    {
       _ASSERTE(IsWindow(hWnd));

       HICON hIcon = NULL;

       if (SendMessageTimeout(hWnd, WM_GETICON, ICON_SMALL, 0,
                              SMTO_ABORTIFHUNG|SMTO_BLOCK, 1000,
                              (DWORD_PTR *)&hIcon))
       {
           if (hIcon == NULL)
           {
               if (!SendMessageTimeout(hWnd, WM_GETICON, ICON_BIG, 0,
                                       SMTO_ABORTIFHUNG|SMTO_BLOCK, 1000,
                                       (DWORD_PTR *)&hIcon))
                   hIcon = NULL;
           }

       }
       else
           hIcon = NULL;

       if (hIcon == NULL)
           hIcon = (HICON)GetClassLongPtr(hWnd, GCLP_HICONSM);

       if (hIcon == NULL)
           hIcon = (HICON)GetClassLongPtr(hWnd, GCLP_HICON);

       if (hIcon == NULL)
           hIcon = LoadIcon(NULL, IDI_APPLICATION);

       return hIcon;
    }

    Есть и еще варианты, как достать иконку, но сначала попробуй это.

  • Тыщ (25.04.08 13:54) [4]
    DVM ©   (25.04.08 13:27) [3]

    Что есть GetClassLongPtr, GCLP_HICONSM и GCLP_HICON?
    Ладно, и без них работает (закомментировал). Спасибо!

    Блин... Какой же я невнимательный дурак!
    Надо было не PostMessage, а SendMessage использовать!

    Вот так работает:

    procedure SaveConsoleIcon;
    begin
     If not User32Loaded then Exit;
     OldIconBig:=HICON(SendMessage(GetConsoleWindow,WM_GETICON,ICON_BIG,0));
     OldIconSmall:=HICON(SendMessage(GetConsoleWindow,WM_GETICON,ICON_SMALL,0));
    end;

  • DVM © (25.04.08 13:58) [5]

    > Надо было не PostMessage, а SendMessage использовать!

    Еще лучше SendMessageTimeout, иначе возможно подвисание при отправке сообщения чужому окну.
  • DVM © (25.04.08 13:59) [6]
    GetClassLongPtr - это GetClassLong (без Ptr)
  • Тыщ (25.04.08 14:17) [7]
    DVM ©   (25.04.08 13:59) [6]

    Хм, через класс тоже можно много интересного получить. Спасибо, буду знать.
 
Конференция "WinAPI" » ProcessID и иконка родительской консольной программы
Есть новые Нет новых   [134433   +22][b:0][p:0.002]