Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Написание небольшой программы


Автор: suseway 25.2.2010, 15:43
Хочу создать небольшую программу, которая бы висела в трее, и по назначенной горячей клавише сворачивала бы активное окно на экране.
Какое средство разработки выбрать для этого и с чего начать, где загрузить? (ориентируюсь на visual c++)

Автор: chaos 25.2.2010, 16:26
Win+D не подходит? smile 
если писать то тебе нужно
1. при старте твоего приложения запихать его в трей и убрать из таск бара
2. определить глобальный хук на клаву и привязать обработчик
3. в обработчике нужно: найти активное окно и послать ему сообщение "свернуться"

вот и весь алкоритмалгоритм

Автор: borisbn 25.2.2010, 17:32
user posted image
хотя это похвальное желание разобраться самому.
По поводу средств разработки посмотри в строрну http://qt.nokia.com/doc/4.6/ + студия на windows или qt-creator под все (условно всеsmile другие ОС 

Автор: suseway 25.2.2010, 17:34
Цитата(borisbn @ 25.2.2010,  17:32)
user posted image
хотя это похвальное желание разобраться самому.
По поводу средств разработки посмотри в строрну http://qt.nokia.com/doc/4.6/ + студия на windows или qt-creator под все (условно всеsmile другие ОС

Возможно ли написание такой программулины на QT в среде под Linux, но чтобы работало на Windows? Если да, то какая среда для этого нужна и с чего начать?

Автор: suseway 25.2.2010, 18:31
Пока имею вот это:

Код

#include <windows.h>
 
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
 //::MessageBox(NULL, "title", "body", MB_OK); 
 HWND hWnd = ::GetForegroundWindow();
// HWND window = FindWindow(NULL, "Debug"); //задается переменная и имя окна

 if (NULL != hWnd) {
     ::ShowWindow(hWnd, SW_SHOWMINIMIZED); 
 }
 return 0;
}



При выполнении этого кода происходит сворачивание активного окна

[UPD]:: Есть вопросы:

1. Как сделать, чтобы после запуска программулины она сворачивала бы активное окно по нажатию на клавишу.
2. И еще, чтобы сама программулина висела в памяти (не закрывалась)

Автор: suseway 26.2.2010, 02:23
Вроде бы решил пока вот так:
Код

#include <stdio.h>
#include <windows.h>

// http://msdn.microsoft.com/en-us/library/ms927178.aspx
#define VK_F6 0x75

// функция вхождений программы WinMain
int CALLBACK KeyboardProc(int nCode, DWORD wParam, DWORD lParam)
{
 HWND hWnd = ::GetForegroundWindow();
 KBDLLHOOKSTRUCT * p = (KBDLLHOOKSTRUCT*)lParam;


 switch(wParam)
  {
  case WM_KEYDOWN:
      //if (keyDown(VK_F6)) ::MessageBox(NULL, "asd", "sad", MB_OK); 

       if (p->vkCode == VK_F6)     
            if (NULL != hWnd) {
                ::ShowWindow(hWnd, SW_MINIMIZE); 
     } 

   break;

  default:
      break;
  }
 
 return 0;
}
 
int APIENTRY WinMain(HINSTANCE hInstance,
             HINSTANCE         hPrevInstance,
             LPSTR             lpCmdLine,
             int               nCmdShow)
{
 
  SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)&KeyboardProc, GetModuleHandle(NULL), 0);
  // цикл сообщений приложения
 
  MSG msg = {0};    // структура сообщения
  int iGetOk = 0;   // переменная состояния
  while ((iGetOk = GetMessage(&msg, NULL, 0, 0 )) != 0) // цикл сообщений
  {

    if (iGetOk == -1) return 3;  // если GetMessage вернул ошибку - выход
    TranslateMessage(&msg);    
    DispatchMessage(&msg);
  }
  return 0;  // возвращаем код завершения программы
}

Автор: chaos 26.2.2010, 09:05
Цитата(borisbn @  25.2.2010,  14:32 Найти цитируемый пост)
По поводу средств разработки посмотри в строрну QT + студия на windows или qt-creator под все (условно все другие ОС  

оффтоп, но "нафига козе баян" ? кросс все равно не получится сделать без написания своих реализация по работе с хуками и окнами

Автор: borisbn 26.2.2010, 10:11
chaos, 

1. 
Цитата(suseway @  25.2.2010,  15:43 Найти цитируемый пост)
Какое средство разработки выбрать для этого и с чего начать


2. 
Цитата(suseway @  25.2.2010,  15:43 Найти цитируемый пост)
создать небольшую программу, которая бы висела в трее


3. Кросс, конечно, не получится, но использовать winAPI или MFC - IMHO есть головная боль

Автор: Alexeis 26.2.2010, 10:27
ИМХО хук нужен только когда нужно запретить передачу событий от клавиатуры, или изменить одни клавиши на другие. Если просто узнать о нажатии клавиш, то есть более экономичное и менее системное решение RegisterHotKey / UnregisterHotKey (глобальный хоткей)

Автор: chaos 26.2.2010, 11:08
Цитата(Alexeis @  26.2.2010,  07:27 Найти цитируемый пост)
ИМХО

 smile 

"пища" для ума
Код

#include <windows.h>

int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    const int nHotKeyId = 0;
    if (NULL == ::RegisterHotKey(NULL, nHotKeyId, 0, VK_F6)) {
        ::MessageBox(NULL, "Hot key F6 is regitered!!!", "Error", MB_OK | MB_ICONERROR);
        return 0;
    }

    MSG msg;
    while (-1 != ::GetMessage(&msg, NULL, 0, 0)) {
        if (WM_HOTKEY == msg.message) {
            const HWND hWnd = ::GetForegroundWindow();
            if (hWnd)
                ::ShowWindow(hWnd, SW_MINIMIZE);
        }
    }

    ::UnregisterHotKey(NULL, nHotKeyId);

    return 0;
}


Цитата(borisbn @  26.2.2010,  07:11 Найти цитируемый пост)
но использовать winAPI или MFC - IMHO есть головная боль 

много тут головной боли?

Автор: suseway 2.3.2010, 18:33
Да, все работает. а реально ли сделать чтобы сворачивалось не глобально а только в определенном приложении, многооконном?

Автор: Alexeis 2.3.2010, 18:49
suseway, можно перечислять и дочерние окна, но не ясно когда остановиться. Представь что курсор будет над кнопкой smile . Ему что придется кнопку сворачивать?

Автор: suseway 2.3.2010, 19:05
Как я понимаю надо смотреть в сторону FindWindow и FindWindowEx.

А сначала получить имя класса приложения при помощи spy32?

Автор: Alexeis 2.3.2010, 20:51
Цитата(suseway @  2.3.2010,  18:05 Найти цитируемый пост)
Как я понимаю надо смотреть в сторону FindWindow и FindWindowEx.

  Это дает главное окно. Для навигации по дочерним нужно EnumChildWindows.

Автор: suseway 3.3.2010, 13:22
Цитата(Alexeis @ 2.3.2010,  20:51)
Цитата(suseway @  2.3.2010,  18:05 Найти цитируемый пост)
Как я понимаю надо смотреть в сторону FindWindow и FindWindowEx.

  Это дает главное окно. Для навигации по дочерним нужно EnumChildWindows.


А с помощью какой утилиты можно узнать имя класса окна?

Автор: suseway 3.3.2010, 15:19
что пытаюсь сделать:

Код

#include <windows.h>

BOOL CALLBACK EnumFunc(HWND hWnd,LPARAM lParam);

int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    const int nHotKeyId = 0;
    if (NULL == ::RegisterHotKey(NULL, nHotKeyId, 0, VK_F11)) {
        ::MessageBox(NULL, "Hot Key F6 is registered!!!", "Error", MB_OK | MB_ICONERROR);
        return 0;
    }

    MSG msg;
    while (-1 != ::GetMessage(&msg, NULL, 0, 0)) {
        if (WM_HOTKEY == msg.message) {
            const HWND hWnd = ::GetForegroundWindow();
            HWND apphwnd = FindWindow("notepad",0);
            if (hWnd && apphwnd) {
                
                EnumChildWindows(apphwnd,EnumFunc,NULL);    
                //::ShowWindow(hWnd, SW_MINIMIZE);
            }
                
        }
    }

    ::UnregisterHotKey(NULL, nHotKeyId);

    return 0;
}

BOOL CALLBACK EnumFunc(HWND hWnd,LPARAM lParam)
{    
    //Здесь делаем все необходимое с нужными окнами 
    //если хотим продолжать дальше перечислять дочерние окна
    //возвращаем ТRUE если не хотим -FALSE
    ::ShowWindow(hWnd, SW_MINIMIZE);
    return TRUE;
}

Автор: Alexeis 3.3.2010, 15:23
Цитата(suseway @  3.3.2010,  12:22 Найти цитируемый пост)
А с помощью какой утилиты можно узнать имя класса окна?

Spy++ или аналоги. Но дело ведь не в том как определить имя окна. Механизм ведь универсальный. У каждого приложения окна называются по разному.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)