2013-03-27 3 views
0

Я создаю приложение, которое должно загружать различные параметры на основе активного окна/программы (например, если вы используете хром, настройки, связанные с Chrome, загружаются при переключении в MS Word загружаются настройки MS Word).Обновление атрибута класса с помощью обратного вызова

Сейчас я работаю над классом, который извлекает правильные настройки из базы данных каждый раз при изменении активного окна. Этот класс также будет иметь метод «LookUp», который возвращает значение на основе последних настроек.

Для того, чтобы описать то, что я пытаюсь реализовать в псевдокоде:

class RecipeBook{ 
    public: 
     RecipeBook(); 
     HWINEVENTEVENTHOOK hEvent; 
     string currentProgram; 
     static VOID CALLBACK WindowCallback(HWINEVENTHOOK hWinEventHook, 
              DWORD dwEvent, 
              HWND hwnd, LONG idObject, 
              LONG idChild, 
              DWORD dwEventThread, 
              DWORD dwmsEventTime); //Actual callback 
     void messageCheck(void*); 
} 

RecipeBook::RecipeBook(){ 
     this->hEvent = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, 
            EVENT_SYSTEM_FOREGROUND, 
            NULL,&WinEventProcCallback, 
            0, 0, 
            WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); 

     Start messageCheck(void*) in separate thread 
} 

void messageCheck(void*){ 
    MSG msg; 
    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
    } 

} 

VOID CALLBACK WindowCallback(HWINEVENTHOOK hWinEventHook, 
              DWORD dwEvent, 
              HWND hwnd, LONG idObject, 
              LONG idChild, 
              DWORD dwEventThread, 
              DWORD dwmsEventTime){ 

     Get the name of the active program from the HWND handle //This is working 
     Update RecipeBook->CurrentProgram 
} 

Проблемы, которые я имею с этим:

1) Не удается получить сообщение проверки для запуска в отдельный поток. Если я запускаю код последовательно, он отлично работает. Когда я пытаюсь икру messageCheck в потоке (с использованием

AfxBeginThread(&messageCheck, &currentProgram, THREAD_PRIORITY_NORMAL, 0, 0,NULL) 

)

это просто не похоже, другой поток создается.

2) Я не знаю, как изменить значения в RecipeBook из обратного вызова. Я думал о возврате имени из обратного вызова, но мне не удалось заставить его работать. Было бы неплохо, если бы я мог просто отредактировать строку из обратного вызова.

3) Я думал просто запрашивать текущую активную программу всякий раз, когда вызывается метод LookUp, но я смог найти только методы, которые получают идентификатор вызывающего процесса, а не активный идентификатор процесса Windows.

Это большой вопрос, но любой совет будет очень признателен!

Спасибо!

+0

Моя первая мысль, что AfxBeginThread требует функцию нити, чтобы соответствовать конкретной подписи: UINT __cdecl MyControllingFunction (LPVOID pParam); Вы должны иметь возможность проверить возвращаемое значение вызова AfxBeginThread, чтобы узнать, есть ли ошибка параметра. – Derek

ответ

0
GetForgroundWindow() 

Это то, что я искал!

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633505(v=vs.85).aspx

По какой-то причине я пытался использовать GetActiveWindow() и всякий раз, когда я увидел окно Forground по какой-то причине я думал фон окна. По электронной почте Ой!

Если кто-либо не может дать хорошее объяснение, как выполнять многозадачность, CALLBACK, я собираюсь просто использовать эту функцию и запрашивать текущее окно всякий раз, когда выполняется LookUp. Не должно быть так часто, и этот процесс не займет слишком много времени.

Для тех, кто заинтересован в том, как вы получите имя процесса из активного окна/ПИД-регулятор с помощью оконной ручки, это то, как я делал это:

DWORD processID; 
LPTSTR processName = new TCHAR[MAX_PATH]; 
DWORD nameSize = MAX_PATH; 
HWND activeWindowH = GetForegroundWindow(); 
DWORD threadID = GetWindowThreadProcessId(activeWindowH,&processID); 
HANDLE processHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_QUERY_INFORMATION,FALSE,processID); 
BOOL nameSuccess = QueryFullProcessImageName(processHandle,0,processName,&nameSize); 

Ура!

Смежные вопросы