C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[76277] Re: IFrameworkInputPane 정의가 반드시 있어야만 가능한 게 아님.
빌더(TWx) [builder] 1089 읽음    2022-03-25 07:24
친구 님이 쓰신 글 :
: 답변 감사드립니다. ^^
:
: 지나가다가 님이 쓰신 글 :
: : 우선 header 파일이 없다면, 컴파일시 헤더파일이 없다는 오류가 발생합니다.
: : 해당 파일은 존재하는데, 사용하는 빌더 버전이 낮아서,
: : IFrameworkInputPane 에 대한 정의가 되어 있지 않은것이 문제입니다.
: :
: : 해당 정의는 Windows 8.1 에서 생긴듯 한데, 빌더 버전을 높이는게 좋은 방법입니다.
: : 굳이 예전버전을 사용해야 한다면,
: : shobjidl.h의 경우, windows sdk에 포함되어 있는 shobjidl.h 파일의 내용을 일부 발췌하여 사용하여야 합니다.
: : 손이 좀 가는 작업일겁니다.
: :
: : 참고로, 엠바카데로 사이트에가면 community 버전을 등록하면 무료로 사용할 수 있습니다
: : 제한적이지만 상업적 사용이 가능합니다.
: :
: : 친구 님이 쓰신 글 :
: : : 안녕하세요
: : : 빌더 6에서 아래 터치 키보드 관련 c++ 소스를 컴파일 하고 싶습니다.
: : :
: : : 컴파일 하면 Undefined symbol 'IFrameworkInputPane' 에러가 나고요
: : :
: : : #include "Shobjidl.h" 에 있어야 하는데 제 해더 파일엔 없더라고요
: : : 이런경우 어떻게 해결이 가능 할까요?
: : :
: : :
: : :
: : : 
: : : #include "stdio.h"
: : : #include "Shobjidl.h"
: : : #include "Windows.h"
: : : 
: : : bool GetKeyboardRect( RECT *r ) {
: : : 	IFrameworkInputPane *inputPane = NULL;
: : : 	bool result = false;
: : : 	HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
: : : 	if (SUCCEEDED(hr)) {
: : : 		hr = CoCreateInstance(CLSID_FrameworkInputPane, NULL, CLSCTX_INPROC_SERVER, IID_IFrameworkInputPane, (LPVOID*)&inputPane);
: : : 		if (SUCCEEDED(hr)) {
: : : 			hr=inputPane->Location( r );
: : : 			if (SUCCEEDED(hr)) {
: : : 				result = true;
: : : 
: : : 				if( r->left == 0 )
: : : 				if( r->right == 0 )
: : : 				if( r->top == 0 )
: : : 				if( r->bottom == 0 )
: : : 					result = false;
: : : 			}
: : : 			inputPane->Release();
: : : 		}
: : : 	}
: : : 	CoUninitialize();
: : : 	return result;
: : : }
: : : 
: : : int main()
: : : {
: : : 	HRESULT hr;
: : : 	hr = CoInitialize(0);
: : : 
: : : 	RECT r;
: : : 	bool result = GetKeyboardRect( &r );
: : : 	printf( "result=%d RECT=%d,%d,%d,%d\n", result, r.left, r.top, r.right, r.left );
: : : 	return 0;
: : : }
: : : 




답변:


터치 키보드가 활성화 되어있는지 아닌지를 확인하기 위해서 IFrameworkInputPane을 필요로 하는 것 같은데...
IFrameworkInputPane 정의가 있어야만 가능한 건 아닙니다.

터치 키보드는 WinRT를 이용해서 만들어진 Universal App 이고...
DWM(Desktop Windows Manager) 환경에서 DirectComposition COM 인터페이스를 이용해서
구현되어 있기 때문에...

다음과 같이 DwmGetWindowAttribute() API 이용해서 체크하면 됍니다.


<Windows 11, RAD Studio 11.1>

//---------------------------------------------------------------------------
#include 
#include 
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
class TouchKeyboard
{
private:
  struct Singleton
  {
    struct Invoke : IUnknown { virtual long _stdcall Dispatch(HWND) = 0; };
    Singleton() {
      auto hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
      if(hr == 0 || hr == 1) {
        bOleInitialized = true;
        if(REGDB_E_CLASSNOTREG == CoCreateInstance(Host, 0, 6, ITip, (void**)&iv)) {
          // inproc COM not running, launch 'TabTip' process
          assert(false && L"Inproc COM not running, launch '%CommonProgramFiles%/microsoft shared/ink/TabTIP.EXE'");
        }
      }
    }
    ~Singleton() {
      if(iv) iv->Release();
      if(bOleInitialized) CoUninitialize();
    }
    static inline bool bOleInitialized;
    static inline Invoke* iv;
  };
  static inline const Singleton _;
  static inline const GUID Host = { 0x4CE576FA, 0x83DC, 0x4f88, 0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76 };
  static inline const GUID ITip = { 0x37c994e7, 0x432b, 0x4834, 0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b };

public:
  TouchKeyboard() = default;
  void toggle() const noexcept {
    if (_.iv) _.iv->Dispatch(GetDesktopWindow());
  }
  bool IsActivated(RECT& r) const noexcept {
    return [&r](auto h, auto _) {
      if (DwmGetWindowAttribute(h, 016, &_, 4), _&2 && GetWindowRect(h, &r)) return true;
      return false;
    }(FindWindowExA(FindWindowA("ApplicationFrameWindow", ""), 0, "ApplicationFrameInputSinkWindow", 0),-1);
  }
};
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  TouchKeyboard tk;
  tk.toggle();

  if(RECT r; tk.IsActivated(r))
    Caption = String().sprintf(L"Visible RECT=%d,%d,%d,%d", r.left, r.top, r.right, r.bottom);
  else
    Caption = L"Invisible";
}
//- END ---------------------------------------------------------------------------






+ -

관련 글 리스트
76270 빌더 6에서 헤더 파일에 없는 함수를 사용하고자 할경우 어떻게 해야 할까요? 친구 897 2022/03/11
76273     Re:빌더 6에서 헤더 파일에 없는 함수를 사용하고자 할경우 어떻게 해야 할까요? 지나가다가 942 2022/03/13
76274         Re:Re:빌더 6에서 헤더 파일에 없는 함수를 사용하고자 할경우 어떻게 해야 할까요? 친구 903 2022/03/15
76277             Re: IFrameworkInputPane 정의가 반드시 있어야만 가능한 게 아님. 빌더(TWx) 1089 2022/03/25
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.