그러면 지역후킹쓰면 되겟네요;
박영목.월천 님이 쓰신 글 :
: 아... 저는 Click에 대한 부작용네 대한 답변이 있는가 하고 들어왔더니... 질문이...
:
: 나그네님 것은 어렵지 않은 데... 키보드훅킹을 하시면 됩니다. 키보드 훅킹 Install, UnInstall 함수를 2개를 만들어 두고... Install 하면 Enter를 치면 동작하게 해둡니다... 그런데 Dialog창을 띄웠을 때는 Enter가 먹으면 골란할 때가 많으니... 키보드 훅을 제거(UnInstall) 하고 Dialog 닫으면 다시 키보드 Install.... 전역으로 할 것 같지 않고 그 프로그램에서 할 것으로 보이니까 훅 함수를 DLL로 만들 필요도 없습니다. 그냥 함수 하나 만들고... 혹 거는 함수 있습니다. 걸고 제거 하시면 되는 데... 지금 프로젝트에고 소스로 사용하고 있을 것인 데.... 에고... 휴...
:
: 아래 소스 올립니다... 참고하시고 수정하시면 됩니다. 키가 Up 될 때 하시려면 고치시면 되고...
: Enter키 어떤 키라도 넣으면 되고.... 그리고 키보드 훅킹으로 찾아 보시면 됩니다. 윈도우 전체를 훅킹하려면...
: 키보드 훅 함수를 DLL로 만드시면 됩니다.... 그렇게 어렵지 않습니다.... 물론 그렇게하면.... 약간... 시스템이 느려지겠지요.... 키보드 칠 때마다 이 함수가 동작할 것이기 때문에.... 그렇게 할 경우는 잘 없더군요...
:
: 아주 초보일 때 전역(dll)으로 해서 사용한 적이 몇번 되었다는 것... 참 나원.... 한 프로그램 안에서 할 때는 아래 처럼 하면 됩니다. 아직도 초보입니다.... 잘 부탁드립니다.
:
:
: <추가>
: 또 질문을 잘 보니... Enter를 어디에서 누르면 그 Enter가 그곳에도 적용이 일어나야 한다면
:
: return 1; 을 삭제하고 CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); 이곳으로 들어가게 해야 합니다. 그렇지 않으면... 컴포넌트에서.. 동작하지 않을 것입니다. 빠져나가니... ㅋㅋㅋ
:
:
:
:
:
:
: bool bCtrlKeyDown;
: bool bShiftKeyDown;
: bool bAltKeyDown;
:
: //--------------------------------------------------------------
: // Hook Procedure - Keyboard
: //--------------------------------------------------------------
:
: HHOOK hKeyboardHook = NULL;
: HHOOK hMouseHook = NULL;
:
: LRESULT CALLBACK KeyboardProcedure(int nCode, WPARAM wParam, LPARAM lParam)
: {
: // By returning a non-zero value from the hook procedure, the
: // message does not get passed to the target window
:
: // KBDLLHOOKSTRUCT2 *pkbhs = (KBDLLHOOKSTRUCT2*)lParam;
:
: int iSelect=0;
:
:
: switch (nCode)
: {
: case HC_ACTION:
: {
: // Check to see if the CTRL key is pressed
:
: bCtrlKeyDown = GetAsyncKeyState( VK_CONTROL )>>((sizeof(SHORT)*8)-1); //GetKeyState(VK_CONTROL);
: bShiftKeyDown = GetAsyncKeyState( VK_SHIFT )>>((sizeof(SHORT)*8)-1); //GetKeyState(VK_SHIFT);
: bAltKeyDown = GetAsyncKeyState( VK_LMENU )>>((sizeof(SHORT)*8)-1); //GetKeyState(VK_LMENU );
: //bAltKeyDown 아마 이 놈은 잘 안 먹을 것 같음... 요즘은 Alt를 잘 쓸 일이 없는 데... Win2000부턴가 시스템키는 빼는 방법이 좀 어려웠는 데... 물론 해내었지만... 이것은 찾아야 하고... shift와 control은 동작할 것입니다.
:
: if( coVar.bHotKey==true ) //(DWORD)lParam & 0x80000000 ) //키보드가 눌러졌을 때만 처리를 한다.
: {
:
: switch( (DWORD)wParam )
: {
: case 32: //Play, Pause
: if( (DWORD)lParam & 0x80000000 )
: MainForm->PlayPause();
:
: return 1;
: break;
:
: case **: //Enter 키값
: if( (DWORD)lParam & 0x80000000 )
: ********* 함수면
:
: return 1;
: break;
:
: }
: }
:
: break;
: }
:
: default:
: break;
: }
: return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam );
: }
:
:
:
: void __fastcall InstallKeyboardHook()
: {
: hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)KeyboardProcedure, 0, ::GetCurrentThreadId() ); //WH_KEYBOARD
: }
:
: void __fastcall UnInstallKeyboardHook()
: {
: if( hKeyboardHook )
: {
: UnhookWindowsHookEx( hKeyboardHook );
: hKeyboardHook=NULL;
: }
: }
: //--------------------------------------------------------------------
:
: void __fastcall InstallKeyboardHook();
: void __fastcall UnInstallKeyboardHook();
:
: 요놈들을 적절한 곳에서 잘 사용합니다.
:
: 물론 이 프로그램 끝낼 때도 UnInstallKeyboardHook();
: 하셔야... 좋겠지요.... 습관적으로 늘 이렇게...
:
:
:
: 나그네 님이 쓰신 글 :
: : 저도 아래 코딩처럼 물론 했었습니다. 그러나 문제의 핵심은 포커스가 폼에 있지 않다면 저 코드가 사실 무용지물이라는 것입니다. 포커스가 스트링그리드나 버튼과 같은 폼내의 다른 컴포넌트에 있을 때는 엔터키를 쳐도 아래 코드가 호출이 되지 않는다는 문제입니다.
: :
: : 제가 원하느 것은 포커스의 위치와 무관하게 동일한 함수의 호출이 필요한 것입니다.
: :
: : 물론 타이머를 이용해서 지속적으로 포커싱을 원하는 버튼으로 바꾸면 되기야 하겠지만 그런 무식한 방법 말고 다른 방법이 없을까 해서 질문을 올립니다.
: :
: :
: : 박영목.월천 님이 쓰신 글 :
: : : Button1->Click(); 이런 형태... 요 근래... 제 프로그램에서 혹 어떤 경우에 누르지 못하는 경우를 발견했습니다.
: : :
: : : 저도 몇년을 사용했는 데... 요 근래 알았다는 것... 프로그램이 부하가 좀 되는 넘이라 그런 지... 이것을 뛰어 넘더군요... 그래서 생각했 보았습니다. 저것도 사람이 마우스로 누르는 것과 같으니... 바쁘면 윈도우가 띄어 넘을 수 있지 않을까? 인터페이스 쪽이라 그런가?
: : :
: : : 그래서... Click(); 안에 있는 놈을 그냥 함수로 하나 만들고... 이것을 Click과 다른 곳에서 호출할 때 사용하도록 바꾸었습니다.... ^^ 혹 나만 그런가? 혹 경험하신 분들 답변 부탁드립니다 ^^
: : :
: : :
: : : 그대의의미 님이 쓰신 글 :
: : : : 나그네 님이 쓰신 글 :
: : : : : 한 화면에 여러개의 컴포넌트가 배치 되어 있습니다.
: : : : : 버튼도 여러개 있고요...
: : : : :
: : : : : 그런데 Enter 키를 누르면 포커스가 어디에 있던지 무조건 한개의 버튼의 클릭이벤트를 실행하고 싶습니다.
: : : : :
: : : : : 한개의 화면상에서 Enter 는 무조건 한개의 버튼 클릭이벤트를 연결시키는 방법을 알고 싶습니다.
: : : :
: : : : void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
: : : : TShiftState Shift)
: : : : {
: : : : if(Shift.Empty() == true && Key == VK_RETURN)
: : : : Button1->Click();
: : : : }
: : : :
: : : : 이렇게하고 프로퍼티에 KwyPreview = true
: : : : 로 만들어주면 해당버튼만 눌러지는것과같습니다