친구 님이 쓰신 글 :
: 답변 감사드립니다. ^^
:
: 지나가다가 님이 쓰신 글 :
: : 우선 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 ---------------------------------------------------------------------------