かに太郎、ただいま開発中 -2ページ目

かに太郎、ただいま開発中

Windowsアプリ作ってます。

C++とMFCから、C#とXAMLにのんびり移行中。

忘れっぽいので、健忘録。

リモートアクセスソフトのTeamViewer と

うちの製品の一部が相性悪い。


サインインした状態で起動すると、

ツールバーやウィンドウ枠が無い。

アプリをさわっていると、アクセス違反やStack Overflow で終了してしまう!


TeamViewer でサインインすると、最小化ボタンの左隣に「クイック接続ボタン」ができるが、

うちのツールバーを、ウィンドウ枠と間違えてるみたい。


「クイック接続ボタン」を非表示にすれば、動く。

非表示にするには、

その他メニュー → オプション → 詳細 → 詳細オプションを表示 → クイック接続ボタン「設定」 → exe名を入れて → OK


COMサーバーに、BOOL * を引数にもつメソッドを作った。


宣言は、こんなん↓。


BOOL GetHoge(BOOL* bHoge);

DISP_FUNCTION_ID(CHogeDoc, "GetHoge", dispidGetHoge, GetHoge, VT_BOOL, VTS_PBOOL)



呼び出し側で、TypeLibからのMFCクラスの追加をした。

ヘッダを見ると、こうなってた。

long GetHoge(long * bHoge)
{
long result;
static BYTE parms[] = VTS_PI4 ;


BOOLの宣言は、

typedef int BOOL;

こうなってるから、

int GetHoge(int * bHoge);

になるなら、納得なのだけど、なんで long になるねん?

まぁ、今作ってるプラットフォームでは、実質同じなので、気にしないことにした。


しかし、

BOOL * を渡そうとしたら、コンパイルエラー!

BOOL bHoge;

pDoc->GetHoge(&bHoge); C2664

long に変えたら、コンパイルは通る。
long bHoge;

pDoc->GetHoge(&bHoge);


でも、実行時に、「種類が一致しません。」とエラーになって、呼べない。


結論 :

BOOL * の引数をもつメソッドは作れない。

ケータイをIS11SHに買い換えてから、

WIN HIGH SPEED のおかげで、通信が早くなった。

受信最大9.2Mbps、送信最大5.5Mbps。

http://www.rbbtoday.com/article/2011/10/05/81723.html  の記事によると、

iPhone 4S の速度は、

SoftBank版が下り最大14.4Mbps 上り最大5.76Mbps、

au版が下り最大3.1Mbps、上り最大1.8Mbps。


iPhone 4S は、WIN HIGH SPEED に対応していない。

秋冬モデルで、WIN HIGH SPEED に未対応なのは、他には、IS11N しかない。

いらねー


スペック比較表見てたら、
ISW11Kが欲しくなってきた。

WiMAXとテザリングとお財布ケータイ!

12月発売か、先だな。

tlb ファイルを配布してもいいんだけど、

忘れそうな気がするので、exeに埋め込もうとした。

rc ファイルに追加すればよい。2箇所ある。


#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

   (略)


3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 17, 1\r\n"
"#pragma code_page(932)\r\n"
"#endif\r\n"
"#include ""res\\ODesign.rc2"" // Microsoft Visual C++ 以外のツールで編集されたリソース\r\n"
"#include ""l.jpn\\afxres.rc"" // 標準のコンポーネント\r\n"
"#include ""l.jpn\\afxprint.rc"" // 印刷/印刷プレビュー リソース\r\n"
"#endif\r\n"
"1 TYPELIB ""hoge.tlb""\r\n" ★追加
"\0"
END


   (略)


#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
#ifdef _WIN32
LANGUAGE 17, 1
#pragma code_page(932)
#endif
#include "res\ODesign.rc2" // Microsoft Visual C++ 以外のツールで編集されたリソース
#include "l.jpn\afxres.rc" // 標準のコンポーネント
#include "l.jpn\afxprint.rc" // 印刷/印刷プレビュー リソース
#endif

1 TYPELIB "hoge.tlb" ★追加
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED



しかし、

ビルドすると、Debug や Release 毎に exe の隣に tlb ファイルができる。(デフォルトの設定では)


リソースエディタで、Condisionの設定をした。

↓Visual Studio での見た目。

かに太郎、ただいま開発中
同じ名前で登録すると、エラーになったので、名前を変えました。

rcファイルをエディタで見ると、


"#ifdef _DEBUG\r\n"
"1 TYPELIB ""Debug\\hoge.tlb""\r\n"
"#else\r\n"
"1 TYPELIB ""Release\\hoge.tlb""\r\n"
"#endif\r\n"



#ifdef _DEBUG
1 TYPELIB "Debug\\hoge.tlb"
#else
1 TYPELIB "Release\\hoge.tlb"
#endif



あれ?


IDR_TYPELIB2 とか、3 は、どこ行った?

検索したら、apsファイルに覚えてた。こいつは、ソース管理してないぞ!

他のPCではどうなるのか?

続きは、またこんど。

既に起動しているアプリケーションのドキュメントや、ウィンドウを、

別のアプリケーションがいじくりたい。


MFCサンプルの mfccalc でやってるんだが、

こいつの readme の「このサンプルでは、次のキーワードを使用します。」には、

肝心なキーワードが抜けていて、なかなか辿りつけなかった。

やっとたどり着いたので、メモっとく。


●サーバー側

オブジェクトのコンストラクタで、RegisterActiveObject を呼んで登録。

こんな感じ。


void CObjectOne::CObjectOne()
{
    HRESULT hr=RegisterActiveObject(GetControllingUnknown(),
        clsid,
        ACTIVEOBJECT_WEAK,
        &m_dwCookie);
}

clsid は、 idl や odl ファイルで定義した、そのクラスのid、↓これ

      [ uuid(5B6EA18B-C28C-495E-A92B-A46D0812D75D)]
       coclass ObjectOne
を↓この形式にしたもの。

static const CLSID clsid =
{ 0x5b6ea18b, 0xc28c, 0x495e, { 0xa9, 0x2b, 0xa4, 0x6d, 0x8, 0x12, 0xd7, 0x5d } };


3つめのパラメータは、

ACTIVEOBJECT_STRONG または ACTIVEOBJECT_WEAK。

強いのと弱いの?


CDocument の派生クラスだったら、

OnNewDocument, OnOpenDocument あたりでやるのがよさそう。



デストラクタで、RevokeActiveObject を呼んで解放。

CObjectOne::~CObjectOne()
{
    if (m_dwCookie != 0)
    RevokeActiveObject(m_dwCookie, NULL);
}

●クライアント側

簡単なCOMのサンプルを見ると、いきなり CreateDispatch してたりするが、

これでは、新たに作られてしまうので、

先に、探しに行く必要がある。


LPUNKNOWN pUnk = NULL;
LPDISPATCH pDisp = NULL;
CLSID clsid;
if(!m_ObjectOne){
    m_ObjectOne = new CObjectOne();
}
if (m_ObjectOne->m_lpDispatch == NULL){
    CLSIDFromProgID (L"TestServ.ObjectOne", &clsid);
    if (S_OK == GetActiveObject (clsid, NULL, &pUnk))
        pUnk->QueryInterface (IID_IDispatch, (void**)(&pDisp));
    if (pDisp)
    {
        // attach to running object
        m_ObjectOne->AttachDispatch (pDisp);
    }
    else
    {
        // create new object
        m_ObjectOne->CreateDispatch ("TestServ.ObjectOne");
    }
}