WEBアプリケーション研究室 開発ノート TOP

WEBアプリケーション研究室 開発ノート 2009年06月

スポンサーサイト

-------- --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

    このエントリーをはてなブックマークに追加

最近C++でウィンドウズアプリ開発に挑戦・・・というか、勉強しています。
どうせならネイティブアプリと思うし、やっぱりWindows根元の部分の理解が進むという意見もありWin32APIでやってます。

まず、Windowを作る部分ですが、これを使いまわせるようにクラス化をしようと思います。で、問題になったのがプロシージャの処理です。ウィンドウプロシージャは


typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
こんな定義になってます。で、Windowクラスメンバ関数のポインタは

LRESULT (Window::*windowProc)(HWND, UINT, WPARAM, LPARAM);
なので、当然ですがWNDCLASSEX.lpfnWndProcには代入できません。代入するにはstaticで宣言する必要があります。

ただ、staticにしてしまうと、staticなプロパティにしかアクセスできないし、全てのインスタンスで共用されてしまうので継承して使いまわすことができません。

そこでインスタンス自身のポインタをstaticなプロパティに保持してstaticなwindowProcの中から呼び出せないか試してみました。※これではまた、別々のインスタンスを保持できません。まさにstatic地獄

こちらのサイトを参考にSetWindowLong/GetWindowLongをつかって実現してみました。

class Window
{
protected:
virtual LRESULT proc(UINT uMsg, WPARAM wParam, LPARAM lParam){}
private:
HWND hWnd;
WNDCLASSEX wc;
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
Window(HINSTANCE hInstance, PTSTR appName);
bool createWindow(bool show=true);
}
実装はこんな感じです。

#include "Gomo/Window.h"

Window::Window(HINSTANCE hInstance, PTSTR appName)
{
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = windowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = appName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

selfInstance = this;
}

LRESULT CALLBACK Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Window* instance = (Window*)GetWindowLong( hWnd, GWL_USERDATA );

if(instance)
{
return instance->prop(uMsg, wParam, lParam);
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

bool Window::createWindow(bool show)
{
//CreateWindowの処理
SetWindowLong( hWnd, GWL_USERDATA, (LONG)this );
}
実際動かしてるものは、プロシージャでswitch文を使いたくなかったのでもうちょっと複雑になってます。話を簡単にするため細かいところははしょって書き換えてますので、コンパイル通らないかもしれません。

まだ、C++は良くわかってないので無茶をしてるかもしれませんが、一応動いてるようです。突込みがあったらコメントいただけると幸いです。

    このエントリーをはてなブックマークに追加

Adobe AIRを試してみました。Flashを持っていたらグラフィカルな部分をGUIで、動きをスクリプトで、ということができるので、Flashにインストールしてみました。
ますランタイムをここからダウンロードできます。

ランタイムは普通にインストールできたのですが、FlashにAirSDKをいれるところで軽く詰まりました。

Googleで検索したり、あの難解なAdobeの公式をウロウロして、それらしいのを見つけてインストールしましたが、入りませんでした。

で結局Flashを起動してアップデイトをかけたらうまくいきました。
起動後作成画面に「Flashファイル Adobe AIR」っていうのが出てれば成功です。

しかし、Adobeのサイトって難解ですよね。平たく言えば使いづらい。長文のページでリンクの色を変えていて、どれがリンクかわかりづらいところもあったし、ID登録のフォームにいたっては編集エラーで戻されたら、編集内容破棄されてましたよ。今時ありえない仕様です。

サイトに来る人のモチベーションが他の商用サイトとは違って強いとおもいますので、胡坐をかいている感じですね。

    このエントリーをはてなブックマークに追加



テスト




この状態だと _onClickDomの中のthisはクリックされたエレメントdivを返します。thisはこのオブジェクト自身をさして欲しいのでそういう時は

Event.observe(dom, 'click', this._onClickDom.bind(this));
とします。

    このエントリーをはてなブックマークに追加

クリックしたら全部選択、尚且つ変更できないようにしたくてやってみました。
ちょうとyoutubeの右上にある動画URL貼り付け用inputのような挙動です。





readonly="readonly"がポイントですかねdisabledにすると選択すらできなくなります。あとはjavascriptでイベントを設定してやればいいので

var target = $("readonly_input");

Event.observe(target, 'click', function(e)
{
target.focus();
target.select();
});
今回はprototype.jsを使用しています。

    このエントリーをはてなブックマークに追加
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。