チュートリアル② ~ウィンドウの描画~概要前節では、コールバックからデバッグ領域に表示するといったものでした。 これだけの単純な仕組みであっても 自分なりの制作物を展開していくことが出来ることでしょう。 単純なウィンドウ表示#include <windows.h> using namespace System; using namespace System::Drawing; using namespace System::Windows::Forms; public ref class ACHelpForm : public Form { public: static ACHelpForm^ f; // 自分自身の置き場 public: ACHelpForm() { SetFormAttr(); // 最初は非表示 this->Visible = false; } public: // 入力補完の候補リストのどれかを選択している時に呼ばれる。 void Update(HWND hWnd, int iListBoxSelectedIndex, String^ strListBoxSelectedItem, int iItemHeight) { RECT rect; GetWindowRect(hWnd, &rect); this->Left = rect.right + 24; this->Top = rect.top; this->Width = (rect.right - rect.left) * 2; this->Height = 160; this->Show(); } protected: // 独立したアプリケーショではなく、子窓のように見せるための工夫 void SetFormAttr() { //タイトルバーを消す。秀丸の中のウィンドウかのように振る舞うための工夫。 this->ControlBox = false; this->Text = ""; this->FormBorderStyle = ::FormBorderStyle::None; this->BackColor = ::Color::Gray; } // このフォームが表示された際にアクティブにならないようにする property bool ShowWithoutActivation { virtual bool get() override { return true; } } // このフォームがマウスクリックされた際にアクティブにならないようにする。 virtual void WndProc(Message %m) override { if (m.Msg == WM_MOUSEACTIVATE) { m.Result = (IntPtr)MA_NOACTIVATE; return; } Form::WndProc(m); } }; extern "C" __declspec(dllexport) int OnCreate(HWND hWnd, LPCTSTR szFileName) { // ウィンドウの作成 if (ACHelpForm::f == nullptr || ACHelpForm::f->IsDisposed) { ACHelpForm::f = gcnew ACHelpForm(); } return TRUE; } extern "C" __declspec(dllexport) int OnListBoxSelectedIndexChanged(HWND hWnd, int iListBoxSelectedIndex, LPCTSTR szListBoxSelectedItem, int iItemHeight) { // そのまま伝達 ACHelpForm::f->Update(hWnd, iListBoxSelectedIndex, gcnew String(szListBoxSelectedItem), iItemHeight); return TRUE; } extern "C" __declspec(dllexport) int OnDestroy(HWND hWnd) { // ウィンドウの破棄 if (ACHelpForm::f) { ACHelpForm::f->Close(); } // このOnDestroyの後に、インスタンスが残っているのに任せるのは不安である。明示的に解放 if (ACHelpForm::f) { OutputDebugString(L"明示解放\n"); delete ACHelpForm::f; } return TRUE; } 再度コンパイル再度コンパイルし、「HmAutoCompleteExPlug.dll」を秀丸ディレクトリにコピーしましょう。 再び、.plファイルを読み込んで、何か入力補完を出し、単語を選択してみましょう。 大切なことはこのウィンドウが、
ということです。 解説全体としては、.NETのフォームアプリケーションの代表的な形そのものです。 // 独立したアプリケーショではなく、子窓のように見せるための工夫 void SetFormAttr() { //タイトルバーを消す。秀丸の中のウィンドウかのように振る舞うための工夫。 this->ControlBox = false; this->Text = ""; this->FormBorderStyle = ::FormBorderStyle::None; this->BackColor = ::Color::Gray; } // このフォームが表示された際にアクティブにならないようにする property bool ShowWithoutActivation { virtual bool get() override { return true; } } // このフォームがマウスクリックされた際にアクティブにならないようにする。 virtual void WndProc(Message %m) override { if (m.Msg == WM_MOUSEACTIVATE) { m.Result = (IntPtr)MA_NOACTIVATE; return; } Form::WndProc(m); } これらは、いずれも先ほどの // 入力補完の候補リストのどれかを選択している時に呼ばれる。 void Update(HWND hWnd, int iListBoxSelectedIndex, String^ strListBoxSelectedItem, int iItemHeight) { RECT rect; GetWindowRect(hWnd, &rect); this->Left = rect.right + 24; this->Top = rect.top; this->Width = (rect.right - rect.left) * 2; this->Height = 160; this->Show(); } この部分は入力補完窓の位置に合わせて、自分自身(Form)が位置や大きさを決めている部分です。 |