PDA

View Full Version : سوال: نحوه دریافت رویدادهای صفحه کلید توسط پنجره مخفی (WS_HIDE)



gh-reza
چهارشنبه 03 تیر 1388, 07:22 صبح
با سلام. لطفا اگر اطالاعاتی در این زمینه دارید با ما در میون بزارید واقعا خیلی ضروریه.
سوال اینه: اگر برنامه ای داشته باشیم که پنجره ای محاوره ای اصلی اونو توسط دستور ShowWindow(hwnd, SW_HIDE) مخفی کرده باشیم چطور میتونیم رویدادهای فشرده شدن کلیدی توسط صفحه کلید رو تشخیص بدیم، تا با تعریف یک کلید ترکیبی پنجره رو از حالت مخفی خارج کنیم.

tdkhakpur
چهارشنبه 03 تیر 1388, 13:11 عصر
سلام
وقتی پنجره مخفی میشود کنترل از پنجره گرفته میشود شما باید توسط برنامه یا پنجره های جانبی به پنجره غیر فعال پیغام ارسال کنید.

Nima_NF
چهارشنبه 03 تیر 1388, 13:54 عصر
کاری که شما می خواهید بکنید به آن global hotkey می گویند. از طریق GlobalAddAtom و سپس RegisterHotKey کلید مورد نظر را تعیین کنید.
سپس هرگاه کلیدهای hotkey در ویندوز فشار داده شد، پیام WM_HOTKEY به همه برنامه هایی که hotkey ها را دریافت می کنند ارسال می کند، از جمله به برنامه شما. که بعد از آن می توانید دویاره برنامه خود را نمایش دهید.

اگر قرار هست تمامی کلید هایی که فشار داده می شوند دریافت شود، باید از hook keyboard در ویندوز استفاده کنید؛ چون برنامه شما پنجره ای ندارد که بر روی آن focus کرده باشد و پیام ها ورودی کیبرد کار کند. (توابعی مثل SetWindowsHookEx که اگر در MSDN و در همین فروم جستجو کنید چند مثال زده شده است)

gh-reza
چهارشنبه 03 تیر 1388, 19:56 عصر
با تشکر از پاسخ های شما


سلام
وقتی پنجره مخفی میشود کنترل از پنجره گرفته میشود شما باید توسط برنامه یا پنجره های جانبی به پنجره غیر فعال پیغام ارسال کنید.

در برنامه مورد نظر قرار نیست بنده هیچ پنجره ثانوی داشته باشم تا پنجره اصلی رو در موقع مخفی بودن کنترل کنه


کاری که شما می خواهید بکنید به آن global hotkey می گویند. از طریق GlobalAddAtom و سپس RegisterHotKey کلید مورد نظر را تعیین کنید.
سپس هرگاه کلیدهای hotkey در ویندوز فشار داده شد، پیام WM_HOTKEY به همه برنامه هایی که hotkey ها را دریافت می کنند ارسال می کند، از جمله به برنامه شما. که بعد از آن می توانید دویاره برنامه خود را نمایش دهید.

اگر قرار هست تمامی کلید هایی که فشار داده می شوند دریافت شود، باید از hook keyboard در ویندوز استفاده کنید؛ چون برنامه شما پنجره ای ندارد که بر روی آن focus کرده باشد و پیام ها ورودی کیبرد کار کند. (توابعی مثل SetWindowsHookEx که اگر در MSDN و در همین فروم جستجو کنید چند مثال زده شده است)

من از SetWindowHookEx استفاده کردم، ولی جواب نداد. شاید پارامترها رو درست انتخا نکردم. ممکنه بفرمائید از کدوم type of hook procedure در پارامتر اول استفاده کنیم و چطور پارامترها رو تنظیم کنیم، من از WH_CALLWNDPROC و WH_KEYBOARD استفاده کردم ولی جواب نگرفتم. در ضمن قبل از درست کردن این تاپیک انجمن رو جستجو کردم و الان هم یه بار دیگه ولی چیزی راجع به موضوع مربوطه، مخصوصا SetWindowHookEx پیدا نکردم.

tdkhakpur
چهارشنبه 03 تیر 1388, 21:55 عصر
در برنامه مورد نظر قرار نیست بنده هیچ پنجره ثانوی داشته باشم تا پنجره اصلی رو در موقع مخفی بودن کنترل کنه

سلام
من متوجه منظورتان نشده بودم. بهتره است روی hotkey به هدف خودتان بررسید ولی فکر نکنم .

Nima_NF
چهارشنبه 03 تیر 1388, 23:51 عصر
hook کردن بحث پیشرفته ای هست، و طرز کار آن به همین سادگی با فراخوانی یک تابع نیست. شما باید یک dll برای این کار بسازید.

مثال برای hook keyboard در این لینک (http://www.codeguru.com/cpp/w-p/system/keyboard/article.php/c5699)



در ضمن قبل از درست کردن این تاپیک انجمن رو جستجو کردم و الان هم یه بار دیگه ولی چیزی راجع به موضوع مربوطه، مخصوصا SetWindowHookEx پیدا نکردم.متاسفانه از وقتی که index گذاری سیستم جستجوی خود vBulletin برای این سایت متوقف شد، پیدا کردن تاپیک های سال های قبل غیر ممکن شده است! چون 2 مرتبه مثال زدم و حتی نتوانستم به تاپیک های سال های قبل خودم هم برسم، حقیقتا حوصله دوباره مثال زدن را ندارم... اگر از همان نمونه مثال فوق و توضیحات مثال MSDN استفاده کنید به جواب خواهید رسید.

gh-reza
پنج شنبه 04 تیر 1388, 00:26 صبح
hook کردن بحث پیشرفته ای هست، و طرز کار آن به همین سادگی با فراخوانی یک تابع نیست. شما باید یک dll برای این کار بسازید.

مثال برای hook keyboard در این لینک (http://www.codeguru.com/cpp/w-p/system/keyboard/article.php/c5699)


متاسفانه از وقتی که index گذاری سیستم جستجوی خود vBulletin برای این سایت متوقف شد، پیدا کردن تاپیک های سال های قبل غیر ممکن شده است! چون 2 مرتبه مثال زدم و حتی نتوانستم به تاپیک های سال های قبل خودم هم برسم، حقیقتا حوصله دوباره مثال زدن را ندارم... اگر از همان نمونه مثال فوق و توضیحات مثال MSDN استفاده کنید به جواب خواهید رسید.

حق با شماست و فایل dll باید استفاده بشه، ولی برنامه من طوری که حتما باید یک exe تنها باشه و هیچ فایل اضافه همراهش نباشه و بهمین جهت با NULL قرار دادن پارامتر سوم SetWindowsHookEx برنامه درست کار نمیکنه.
ولی مشکل من با استفاده از RegisterHotKey حل شد. این هم برنامه مورد نظر منه که اینجا قرار میدم تا اگه کسی نیاز داشت استفاده منه:



#define IDC_GLOBALHOTKEY 100
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_HOTKEY:
UnregisterHotKey(hwnd,IDC_GLOBALHOTKEY);
ShowWindow(hwnd, SW_SHOW);
ShowWindow(hwnd, SW_SHOWDEFAULT);
break;
case WM_SIZE:
if(wParam == SIZE_MINIMIZED)
{
RegisterHotKey(hwnd,IDC_GLOBALHOTKEY,MOD_ALT,'S');
ShowWindow(hwnd, SW_HIDE);
}
break;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;

}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
TCHAR szAppName[] = TEXT("GlobalHotKeyTest");
MSG msg;
WNDCLASS wndclass;
wndclass.style = NULL;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = (HBRUSH) (HBRUSH) (COLOR_WINDOW),
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
RegisterClass(&wndclass);
HWND hWnd = CreateWindow(szAppName,TEXT("Global HotKey Test"),
DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_BORDER | WS_SYSMENU,
CW_USEDEFAULT ,CW_USEDEFAULT ,
184,210, NULL,NULL,hInstance,NULL);

ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}