コンソールアプリを,DOS 窓なしで GUI から呼び出す。

// コマンドライン
LPTSTR lpCommandLine;
lpCommandLine = "app.exe";

// パイプの作成
HANDLE hReadPipe, hWritePipe;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
::CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);

// STARTUPINFO
static STARTUPINFO StartupInfo;
static PROCESS_INFORMATION ProcessInfo;

::ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow = SW_HIDE;
StartupInfo.hStdOutput = hWritePipe;

::CreateProcess(
    NULL,
    lpCommandLine,
    NULL,
    NULL,
    FALSE,
    0,
    NULL,
    NULL,
    &StartupInfo, &ProcessInfo);

char buf[255];
unsigned long num;
::ReadFile(hReadPipe, buf, 255, &num, NULL);
if(::WaitForSingleObject(ProcessInfo.hProcess, INFINITE) == WAIT_OBJECT_0)
{
    DWORD res;
    ::GetExitCodeProcess(ProcessInfo.hProcess, &res);
    CloseHandle(ProcessInfo.hProcess);
}
::CloseHandle(hWritePipe);
::CloseHandle(hReadPipe);

これを使えば Java コンパイラを呼び出したりとかで統合環境を作ったりできるかな。いつかやってみたい。

# 2000.05にもう少しちゃんとしたものを載せた。

ILS2,タイマーを 5ms ごとにしたら,描画・通信の同期の関係で異常な重さとなった。

下のミス。リリースバージョンでしか出ないバグで,デバッグに時間がかかった。

if(p != NULL)
{
    p = new char[10];
}

これでは条件が逆で,正しくは

if(p == NULL)
{
    p = new char[10];
}

デバッグでは値が NULL 以外に割り当てられるが,リリースでは値が NULL になったりならなかったりで動作がおかしくなる。

リリースのデバッグ情報を生成し,やっと見つけた。

同じ値の char 同士を比較したのに値が違う,と言われる。signed と unsigned を比較していた。

ILS2 DirectPlay のイベントスレッド,終了のためにイベントをもう 1 つ用意する。

while(1)
{
    // イベントを待つ
    HANDLE hHandles[2];
    hHandles[0] = m_hDPEvent;
    hHandles[1] = m_hDPKillEvent;
    if(::WaitForMultipleObjects(2, hHandles, FALSE, INFINITE) == WAIT_OBJECT_0 + 1)
    {
        // 終了イベント
        return;
    }
    else
    {
        処理
    }
}

のようにするとスッキリする。


VB から VC++ DLL を使う。VC++ で,MFC 拡張 DLL を作成し,

"func.h"
#ifdef __cplusplus
extern "C" {
#endif
int APIENTRY func();
#ifdef __cplusplus
}
#endif
"func.cpp"
int APIENTRY func()
{
    return 0;
}

で公開する関数を作成。この中からはクラスも呼び出せる。

次に def ファイル。

"library.def"
LIBRARY      "DialUpCommon"
DESCRIPTION  'DialUpCommon Windows Dynamic Link Library'

EXPORTS
    func=XXXXXXXX

XXXXXXXX の部分は内部名。@ がたくさん付いてるやつ。

VB 側

Private Declare Function func Lib "library.dll" () As Long

Private Sub Command1_Click()
func
End Sub

とする。その際,開発環境からは DLL をフルパスにするか,DLL をパスの通っている場所に置かなくてはダメだった。

DLL を作成。inline を書くのを忘れ,メソッドが 2 回定義され,DLL リンケージが違うと言われる。


実行ファイル名の取得方法。グローバル変数 _pgmptr を参照する。


プロセス ID の取得方法。_getpid() を使用する。

SSH を使ったメールサーバーへの接続を試みる。Port Fowarding の設定をし,メールサーバーを指定,TTSSH を起動,その後 Outlook Express で,ローカルのポート経由でメールの送受信ができることを確認した。


大学に FTP 接続が成功する。通常通りに ssh の設定をし,FTP 側の設定を,ホストは localhost とし,さらに「PASV を使用」することで ok。

# なんだけど,PASV って何なのか知らない。今度調べてみよう。


Denasu System 以外のある Web ページに PGP 公開鍵を置く。でそのファイルを HTML Lint でチェック。URL に空白が含まれているとか言われる。確かに公開鍵のファイル名にはスペースがある。スペース部分を %20 と表記することで解決。と,ここで % をどう表記するかちょっと悩んだが,ここは URL じゃないのでこのままでいいワケで。

Win98 から ssh を使う。

  1. TTSSH,Tera Term Pro をインストール
  2. ssh-keygen.exe -C メールアドレス で鍵を作成
  3. Identity.pub を authorized_keys にコピーし,FTP で接続先の ~/.ssh/ に置く
  4. TTSSH を起動すると Tera Term Pro が起動し,接続先を指定,ポート 22 で接続。その際 Use RSA key to log in を指定し,鍵の場所も指定しておく

で ok。

Direct3D と 2D を重ねる方法。最初 2D の上に 3D を描いてうまくいかなかったが,Direct3D の Clear を,2D 描画の前で行うようにすればよい。

VC。アプリケーションの拡張子を後から変える方法

String Table の IDR_MAINFRAME を

xxxnnxxxnxxx File (*.xxx)n.xnxxx.Documentnxxx Document

のようにする。(xxx が拡張子)

Direct3D,Viewport の ForceUpdate で画面が更新されなくて困る。原因は ForceUpdate の 3,4 番目の引数が幅,高さだと思っていたこと。実際はクライアント座標。

DirectDraw カラーキーについて

DirectDraw のカラーキーは,実際のハードウェア,BPP などに対応する値を指定してやる必要がある。1 番確実な方法はサンプルのように,サーフェスに GDI で描画をし,値を読み出すこと。

DWORD CDirectDraw::DDColorMatch(LPDIRECTDRAWSURFACE pSurface, COLORREF rgb)
{
    DWORD result;
    COLORREF oldrgb;

    HDC hdc;

    // GDI を使って色を置く
    if(rgb != CLR_INVALID && pSurface->GetDC(&hdc) != DD_OK)
    {
        return 0;
    }

    // 前の値を保持
    oldrgb = ::GetPixel(hdc, 0, 0);

    // 色を置いてみる
    ::SetPixel(hdc, 0, 0, rgb);

    pSurface->ReleaseDC(hdc);

    // ハードウェア依存の値を読み込む
    DDSURFACEDESC ddsd;
    ddsd.dwSize = sizeof(DDSURFACEDESC);

    HRESULT hres;
    while((hres = pSurface->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
    {
        ;
    }

    if(hres == DD_OK)
    {
        result = *(DWORD *)ddsd.lpSurface;

        // BPP に対する修正
        if(ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
        {
            result &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1;
        }

        pSurface->Unlock(NULL);
    }

    // 書き込んだ値を元に戻す
    if(rgb != CLR_INVALID && pSurface->GetDC(&hdc) != DD_OK)
    {
        return 0;
    }

    // 色を置いてみる
    ::SetPixel(hdc, 0, 0, oldrgb);

    pSurface->ReleaseDC(hdc);

    return result;
}

Direct3D,メッシュを見えなくするには,Frame.DeleteVisual すればよいが,メッシュの参照がなくなり,メッシュが削除され,もう 1 度表示するときに困る。これを防ぐには先に Mesh->AddRef() をしてやればよい。

DirectSound で音が鳴り終わったことを検出する為に IDirectSoundNotify を使う。DIRECTSOUNDBUFFER 作成時のフラグに DSBCAPS_CTRLPOSITIONNOTIFY を指定するのを最初忘れた。

DirectSound,弾を撃つバッファを static で作ったが,複数の音が鳴らない。これは別々にバッファを用意するしかないようだ。

DirectInput。GetDeviceData が Release フルスクリーンでうまくいかなかった。原因は第 3 引数が入出力両用ということに気付かず,初期化しないまま渡していたからだ。

SendChatMessage を使うために DirectPlay インターフェースを IDirectPlay3 に。しかしインターフェースがかなり変わっていて戸惑う。

結局 SendChatMessage はロビーを使わないとだめなので使わなかった。

DirectSound が初期化できなかった。原因はサスペンドした時にサウンドカードが使えなくなってたため。もう一度差し直すことで解決。

スタティックライブラリにリソースを埋め込む方法。[挿入] – [リソース] でリソースを作成,その後プロジェクトに *.rc を追加する。

DirectX の簡易ライブラリを作ろうと思う。使いたい DirectX ラッパークラスを継承するというものにしようと思う。


スタティックライブラリの作り方。何度かやってるがいつも迷うのでここに書いておく。新規ワークスペースで Win32 Static Library を選び,プリコンパイル済みヘッダ,MFC サポートを on にする。


DirectSound。DSound.h をインクルードする前に MMSystem.h をインクルードする必要がある。ちなみにライブラリは DSound.lib と WinMM.lib。


Information の r が抜けていた。全部直す。

ILS2 で面白いミス。

if(m_pDDSOffScreen->BltFast(MESSAGE_X, MESSAGE_Y, m_pDDSMessage, CRect(0, 0, MESSAGE_WIDTH, MESSAGE_HEIGHT), DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT) != DD_OK)

m_pFrameScene->Move(D3DVAL(1.0));

のようなことをやって,Move されずに悩んだ。if 文の中身を忘れて次の文が実行されなかったのだ。


クラス情報にアクセスできないとか言われる。対処法は,dsw,dsp を除いて clw などを消せばよい。


Surface の GetDC を使う際,ReleaseDC を忘れて次に呼び出されたときに固まった。よくやるので気を付けねば。


SetOrientation で,回転した場合速度ベクトルが更新されなくて困る。これは一旦絶対座標で速度を 0 にしてから速度を絶対的に設定することで解決。

Direct3D,テクスチャは 2 の n 乗でないと SetTexture でエラーが出るようだ。ていうかそんな制限どっか書いてあったっけ?

テクスチャがどうやってもできないと思ってふと裏から見るとちゃんと見られる。でも何故裏にできる?

ということでよく調べると座標系を勘違いしていた。ヘルプを見てやっと座標系を理解できた。しかしカメラ,ライトは z 方向を向くとかはどこにも書いてないような。試行錯誤でやっと分かってきた。

念のため。SetPosition は自分のフレームの位置をベース座標で指定する。SetOrientation は自分のフレームの向きをベース座標で指定する。その際,第 2 ~ 4 引数は自分の z 軸をベース座標で表した値,第 5 ~ 7 引数は自分の y 軸をベース座標で表した値である。

Direct3D,X ファイルをリソースからロードしようとして失敗する。見つからないと言われる。D3DRMLOADRESOURCE の loadResource.lpName が LPCTSTR なのが不思議に思ったのだが,結局リソース ID を MAKEINTRESOURCE で変換することで解決。

D3DRMLOADRESOURCE loadResource;
loadResource.hModule = AfxGetInstanceHandle();
loadResource.lpName = MAKEINTRESOURCE(RESOURCE_ID);
loadResource.lpType = "X";
pMeshBuilder->Load(&loadResource, NULL, D3DRMLOAD_FROMRESOURCE, NULL, NULL);

VisualC++6.0 の,Doc-View を使わない設定だと,AppWizard で LoadStdProfileSettings が生成されない。ILS2 に以下の部分を追加

LoadStdProfileSettings();

Direct3D の初期化をする。ぷぅさんからテストデータがあがったので試してみたいのだ。しばらくやってると妙に動作が重い。ふと時計を見ると他の時計より 30 分ばかり遅れている。おや? と思って修正しようとすると,明らかに時間が進むのが遅い! ていうか何だコリャ。熱くなりすぎておかしくなったのか? ともあれ時間が遅れるとはビックリ。ちなみに再起動したら直った。

ILS2 を進める。

クライアントウィンドウに対するメインウィンドウの合わせ方

AdjustWindowRectEx を使う。これはあるウィンドウサイズ,あるメニューに対してメインウィンドウをどのくらいにすればよいかを返す関数で,例えば CMainFrame::PreCreateWindow で

CRect rectClient(WINDOW_BASE, WINDOW_BASE, WINDOW_BASE + WINDOW_WIDTH, WINDOW_BASE + WINDOW_HEIGHT);
::AdjustWindowRectEx(&rectClient, cs.style, NULL, cs.dwExStyle);
cs.x = rectClient.left;
cs.y = rectClient.top;
cs.cx = rectClient.Width();
cs.cy = rectClient.Height();

のように使う。


で,ウィンドウモードだが,なかなかうまくいかなかった。原因を調査していると,Primary Surface に BltFast しているのがいけないらしい。Blt ならうまくいく。何故だろう。

ILS2 で使用する Sound ライブラリ。なんとか wav ファイルの再生が完成。これで Direct Sound もいけるだろう。


ウィンドウのサイズを固定にする方法。例えば AppWizard で作ったものなら,

cs.style &= ~(WS_MAXIMIZEBOX | WS_THICKFRAME);

としておけば ok。

Apatch 原因が分かった。ホームディレクトリのディレクトリは最低限 701 でなければ www…/~user/ は読めないらしい。Slackware の時はデフォルトで 755 になってたってことだろう。ちなみに設定ファイルは CGI の部分以外は元に戻しても大丈夫だった。

次は CGI。Slackware の時も起動しなかったが,Turbo でも起動しない。しかしさっきの問題を解決するのに設定ファイルをきちんと勉強したので大丈夫。srm.conf に

AddHandler cgi-script .cgi

と書かれているので .pl ではデフォルトで実行されないのだろう。

AddHandler cgi-script .cgi .pl

として解決。

Apache 状況変わらず。設定ファイルは間違ってないような感じだが…


Denasu System のカウンタを SSI に変える。メインページのファイル名を index.shtml にし,counter.pl を修正。最初日本語を EUC にするのを忘れた。ちなみに拡張子を shtml にしても今まで通り http://www.eva.hi-ho.ne.jp/minoru-f/ で表示される。ちょっと心配してたのでひと安心。

起動しない。どうやら Hi-HO の許す include 方式(私命名)では Content-type がいるらしい。これを付けて再試行。おお。うまくいった。

何故 SSI にしたかというと,HTTP_REFERER をきちんと作用させるためだ。今までの img 方式(同じく私命名。img のソースに CGI を指定する。)では,呼び出し元が Denasu ページなので,HTTP_REFERER が Denasu ページになっていた。これからはやっと他のページが表示されるだろう。ひょっとすると Infoseek からの検索キーワードも分かるかも知れない。ちなみに Pha-jtd 氏のページ のリンクで動作を確認。

Windows での外付けハードディスクがおかしい。書き込み中に
ブルースクリーンになる。なんか Linux を最初のパーティションにしたのが
問題っぽい。仕方がないのでフォーマットして Turbo Linux 再インストール。

再インストール時,初回インストール時に入れてなかった httpd を入れておいた。
これでいろいろできるかな。

Apache の設定。一応 http://Lelie/ で Apatch のページは出てくるものの http://Lelie/~Mortarco/ が出てこない。PHT メッセージボードを参考に Apatch の設定ファイルをいじってもダメ。どうなのか。

Turbo Linux。ネットワークカードの認識を試みる。とりあえず NE2000 互換で認識するように,

/etc/conf.modules

alias eth0 ne

と記述。ここに IO ポートアドレス,IRQ を

option ne io=0x*** irq=*

と指定することもできるが,これは自動で認識させるので指定しない。

しかし依然動かない。いろいろ調べて,

/sbin/route add -net 192.168.1.0 netmask 255.255.255.0 dev eth0

とすることでうまくいった。Slackware ではいつの間にかちゃんと設定されたのだろう。何にせよ原因が分かってよかった。

ちなみにこれは Slackware では

/etc/rd.c/rc.inet1

に書いておくらしいが,Turbo Linux ではこのファイルはないので,

/etc/rd.c/rc.local

の最後に記述し,再起動したところ,うまくいった。

残る問題は Turbo Linux とループバックのカーネルのバージョン違いだ。

Turbo Linux 日本語版 4.0 インストールを試みる。1 度目は X Window のテストをせずに,自分で XF86Config(Slackware のもの。XFree86 のバージョンが 3.3.3.1 のため Chipset は Cyber9388)を入れる。インストールはテキパキ完了。あとは起動。今まで通り Plamo の起動方法で起動してみる。

カーネルのバージョンが違うとか警告が何回か出るが,すっと起動する。おお。スゴイ。まあとりあえずこれでいいだろう。その内何とかしよう。

# と思いつついつまでもそのまま。特に問題がでないからなあ。これでいいかなあ。

パーティション領域が 1.5GB じゃ少ないかな。Complete インストールだし。と思ってパーティションを 2GB にして再インストール。をしたんだけどこの時点で外付け HD の Windows パーティションが読めなくなった。7GB のデータが! ていうかほとんどデータ入れてなかったので別に影響はないけど。インストールを続ける。今回は X のテストをしてみる。ウム。大丈夫。Vine Linux では見られなかったテスト成功画面が見える。いい世の中になったもんじゃ。てな感じで感動。

Window Manager は話題の GNOME にしてみた。さて使い勝手は…。なんかごちゃごちゃしてるけどまあなんかよさげ。特にファイルマネージャ(だっけ?)がよい。

いろいろ試す。とりあえずインストールで認識しなかった PCMCIA NIC カード。turbonetcfg でネットワークを設定。ping っと。ウーム。ダメだ。まあ Slackware でも最初はダメでカーネルの再構築とかいろいろやってるウチに何故かできるようになったワケだが。原因が分かってない分ここで苦労させられるのか。ふぅ。

さて。1 番やりたかった Java2(pre-v1)。とりあえず Pha-jtd 氏ご推薦の Swing デモ。おおっ。起動した。嬉しいですな。これで Windows – Linux – SunOS 統一ソフトウェア開発の第 1 歩を踏み出せた。ていうか学校の SonOS5.0 で Java2 は動くのだろうか。

ということで疲れたので Turbo Linux4.0 の最大の目玉,ATOK12 は後回し。ていうか PHT のメッセージボードで「余り使えない」というのが分かってるので余り期待はしていない。まあ Java2 と Wnn6 が動けばいいや。あっと。EGCS も試したい。

Linux,ふと見るとメモリを 64MB しか認識していない。これは loadlin の引数を

loadlin vmlinuz initrd=extroot root=/dev/sda2 mem=128M

とすることで解決。


会議室,New に対応。

Linux,長いことできなかった Ethernet 接続が成功した。netconfig をもう 1 度やり直しただけなのだが。むう。原因が分かってないと次にインストールしたときに苦労しそうだ。

一応どう設定したか。

ホスト名
Lelie
ドメイン名
xxxx
ループバックのみを使用
No
IP
192.168.1.2
ネットワークマスク
255.255.255.0
ゲートウェイアドレス
(NULL)
DNS
使用しない

ここで,

ping Lelie
telnet Lelie
ftp Lelie

が成功し,

http://xxxx/~Mortarco/

で ~/public_html/index.html が表示された。

さらに旧デスクトップ機 Xe(PC-9821,Win95)の方から Lelie にアクセス。問題なし。windows/hosts に Lelie を入れれば Lelie にアクセスもできる。

次に Lelie 側の hosts ファイルに Xe を付け加える。ping などが一通り成功。まあ成功したからよしとする。

あと CGI がまだ使えないが。まあそのうちやろう。って考えてみれば C で CGI とか Java で CGI とかもやればできるんですかね。サーブレットとか。そのうち挑戦してみたい。