VC++開発記
VC++の奮闘記ってとこです。
適当にやった事をずらずら書いてます。
[ 前の開発記 ]
1月23日 鬼ミニ
調子に乗ってまた鬼ミニアプリを作成。
今度は前にMFCで作ったヘボアプリをAPIのみで作り直してみた。
ファイル内からURLを抜き出してリストを作るプログラムで簡単そうだったから。
問題はファイルの操作でMFCではCFileクラスを使っていたがそれは使えない。
他の関数でファイル操作が出来れば後は前とほぼ同じで良い。
まずはfopen()を使用してみる。
しかしリンク時にエラーが出てコンパイルできない。
どうやらfopen()は使えないようだ。
今度はifstreamクラスを使ってみたがこれもリンクエラーが出る。
うむむ、、、やはりこの技は制限が厳しい。
ファイル操作のAPIが無いか調べてみたらHELPに乗っていた。
ファイルのオープン(と言うかハンドルの取得)はCreateFile()
ファイルに書き込むにはWriteFile()
ファイルから読み込むにはReadFile()
ファイル(ハンドル)をクローズするのにCloseHandle()
と使うのはこんなところ。
しかしAPIは何故こんなにも引数が多いのか。
CreateFile()は7つ、WriteFile()・ReadFile()は5つも有る。
こりゃ普段使う人はいないな。SDKならfopenとかifstreamが使えるし。
こいつはとてもメンドクサイ。
何とか訳のわからない引数の意味を調べてファイルの操作に成功。
今度はAPIのみだからリンクエラーも当然なし。
当初の予定よりも、ものすごく苦労してしまった。
今回のアプリのサイズは3KBだった。ちょっと長かった分少し大きい。
MFCで作ったやつは6KBだったからあまり小さくなっていない感じがする。
でもMFCでスタティックライブラリ使用版と比べれば天と地の差か。
MFCでスタティックリンクすると100KBは余裕で超えるからな。
同じ条件で言えば3KB対100KB以上。
やっぱ凄いわ。
1月22日 曝ミニ
昨日の技を使い曝ミニアプリを作ってみた。
どんなアプリかと言うと実行するとPCの電源を切るプログラム。
使う関数は1つだけ。ExitWindowsEx()のみのアプリ。
コンパイルしてみると何と実行ファイルサイズが1.5KBだった。
WinMain()だけのプログラムは2KBだったのにそれよりも小さくなっている。
しかしWin2000で実行してみると何も起こらない。Win98だと動くのに。
もしかしてExitWindowsEx()はNT未対応かと思いヘルプを見たら
NTでは電源を切るには特権と言うものが必要らしい。
特権の取得の仕方は調べたらすぐ分かった。
しかし何故NTでは特権なんか取らなければならないのだろう。
というかこんなに簡単にプログラムで特権が取れるのなら
特権で保護している(?)意味が無いように思えるが・・・。
結局特権を取得するAPIを追加したらサイズは2.5KBになってしまった。
ま、それでもかなり小さいんだけどね。
以下電源を切るアプリのソース。極小。
// WinOff.c #include <windows.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { // 特権の取得 HANDLE hToken; TOKEN_PRIVILEGES tkp; OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken ); LookupPrivilegeValue( NULL,SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid ); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0); // 電源OFF ExitWindowsEx(EWX_SHUTDOWN,0); return 0; }
1月21日 激ミニ
前に実行ファイルのサイズを小さくする方法を色々試していたら
実行ファイルのサイズを減らす事に成功した。
最初はファイルの拡張子を.cppにしていたがそれを.cに変えたら上手くいった。
やり方はまず下のソースをコンパイルする。このときファイルの拡張子は.cにする。
// diet.c #include <windows.h> void __cdecl WinMainCRTStartup( void ) { int mainret; char *lpszCommandLine; STARTUPINFO StartupInfo; lpszCommandLine = GetCommandLine(); if ( *lpszCommandLine == '"' ) // Check for and handle quoted program name { do{ lpszCommandLine++; }while( *lpszCommandLine && (*lpszCommandLine != '"') ); if ( *lpszCommandLine == '"' ) lpszCommandLine++; } else // First token wasn't a quote { while ( *lpszCommandLine > ' ' ) lpszCommandLine++; } while ( *lpszCommandLine && (*lpszCommandLine <= ' ') ) lpszCommandLine++; StartupInfo.dwFlags = 0; GetStartupInfo( &StartupInfo ); mainret = WinMain( GetModuleHandle(NULL), NULL, lpszCommandLine, StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT ); ExitProcess(mainret); }
コンパイルして出来たdiet.objファイルを今度は実行ファイルのサイズを減らしたい
プロジェクトのソースがあるディレクトリにコピーする。
次にプロジェクトを立ち上げ、プロジェクトの設定を開き、リンクの
オブジェクト/ライブラリ モジュール(L)の欄の先頭にdiet.objを追加する。
この時設定の対象はReleaseにしておく。Debugだとリンク時にエラーになる。
これでコンパイルすればサイズが激減する。
ただしこれはAPI以外を使うとリンク時にエラーになる事があるから
難しいプログラムには使えないけど。
しかしこいつは面白い。ものすごく小さくなる。
28KBのファイルが/opt:"nowin98"と組み合わせたら2KBまで激減した。
これは癖になりそうだ。
1月20日 全画面
昨日作ったビットマップを画面一杯に表示させようと思う。
それには2通りのやり方が有る。
まず、ビットマップ自体を画面一杯拡大させて表示させる方法。
この方法が無難だと思うが拡大させる処理に時間ががかるようだ。
ぐるぐるはスピードが遅いと見難いものになるのでこれはあまり良くない。
と言う訳で別の方法。画面の解像度を640×480にしてやれば良い。
そうすれば拡大する必要もなくるし画面の大きさを取得する必要もなくなる。
と言う訳で解像度の変更の方法を調べたらあっけなく発見。
解像度を変更する事に成功した。が、元に戻せない。
解像度を変える前に現在の解像度を調べなければならないがその方法が分からない。
解像度だけを調べるならRECTで分かるけどディスプレイモードはそれだけではないのだ。
使用色数や周波数など他にも調べる必要がある。
現在のディスプレイモードの取得方法を調べてみたが見つからない。
また壁にぶつかってしまった・・・。
1月19日 絵
ぐるぐるの表示させる絵を作り直す。
絵の大きさを640×480にして渦巻きを真ん中だけじゃなく端の方まできちんと書き直した。
この絵は人が描こうと思っても無理だけど規則的な絵なのでコンピュータならお手の物。
ただその計算式を考え出すのは人間でかなり頭が痛い。
でも前にN88互換BASICで作ったロジックがあるのでそれを今回も流用した。
VCに移植しようと思ったけどいまいちVCのビットマップ関係は分からないのでやめる。
N88互換BASICはビットマップ関連を扱うのが容易で使いやすい。
ただ、非常にスピードは遅いが。
渦巻きを描くBASICのソースはこんな感じで。
10 DIM X(7,1),Y(7,1),R(7) 20 FOR J=0 TO 17 30 FOR I=0 TO 7 40 R(I)=I*45+J*5 50 X(I,0)=0 60 Y(I,0)=0 70 NEXT 90 CLS 100 DIM X(7,1),Y(7,1),R(7) 110 FOR I=0 TO 7 120 X(I,1)=SIN(3.14*R(I)/180)*Z 130 Y(I,1)=COS(3.14*R(I)/180)*Z 140 LINE (320+X(I,0),240+Y(I,0))-(320+X(I,1),240+Y(I,1)) 150 X(I,0)=X(I,1) 160 Y(I,0)=Y(I,1) 170 R(I)=R(I)+5 180 NEXT 190 Z=Z+1 200 IF Z<420 THEN 110 210 GET@ (0,0)-(639,479),A(0) 220 N$="guru"+MID$(STR$(J+1),2,2) 230 BSAVE N$,A(0) 240 Z=0 250 NEXT
まず8本の線を用意し初期角度を45度ずつずらしておく。
SINでx軸、COSでy軸の位置を角度R求めZで等倍して少しずつ大きくし点を保持。
角度Rを5度傾け点を取得し以前の点まで線を引く
それと同じ事を初期角度を変えておいた8本の線ぜんぶ繰り返す。
これを繰り返し画面一杯になった所で画面を640×480に切り取りBMP保存。
さらにこの作業を全ての初期角度を5度ずらし18回繰り返すと絵の元が完成。
後は1枚づつペイントで色を付けてモノクロで保存しなおして最終完成。
ふう、サインやコサインなんか高校時代にやったっきりで
使い方を思い出すのにメッチャ疲れたワイ。
1月18日 DEGITAL@NET
ネットサーフ中いいものを見つけた。
フリーのレンタルWEBスペースで容量5MB、CGI可、広告無し、POPメールアカウント
おまけにドメインアドレスが貰えると言う優れもの。
HPスペースは全然余裕だけど条件の良いものだから、ついサインアップしてしまった。
さて、このスペースをどうしよう。今の所転送にしてあるがほとんど意味無し。
CGIが使えるからCGI置き場にでもしようかと思ったが
MomoたろうでCGI使えるからあんまり必要ない。
利用規約を見るとgccが使えるようなのでCのCGIを作るのに使えるかも。
でもtelnetやSSIは使えないみたいなのにどうやってコンパイルするのかな。
これ等が使えなければgccは使い様が無いぞ。
もしかしたら何か別の方法があったりして。
とりあえず掲示板で質問しておいたけど返事返ってくるかなぁ。
ま、とりあえずこのスペースは転送って事で。
でも何にも無しだと寂しいからミラーとして公開する事にした。
前からジオもミラーとしてリンクしておかなければと思っていたからちょうど良い機会だし
ミラーサイトへジャンプできるページを作成。
掲示板も仕様を変更した事だし、一緒に更新しておいた。
アクセス解析も公開しようと思ったけどCGIのソースをいじって背景色とか
タイトルの表示とか変更しなくてはいけないからメンドクサイ。
アクセス解析の公開はまた今度って言う事でいいか。
1月17日 掲示板
前々から思っていた事だったけどサポート掲示板の表示方法を
ツリーよりもスレッドの方が良いような感じがしていた。
しかしスレッド表示だとスレッドが長くなった場合レイアウトが崩れ醜くなる。
そこでカスタマイズを強力にして表示方法を変えた。
まず全体に掛かっていたテーブルタグを外し、記入部分と内容部分を切り離した。
これでスレッドが長くなっても記入部分がずれる事はなくなり
ついでにテーブルタグを外した事で表示速度も高速になった。
後はレスを付ける時、いちいち内容を見てから返信を押さなくても良い様に
返信用の画面自体に内容を表示させようと思う。
これはかなり大掛かりになりそうだから明日やる事にしよう。
1月16日 返事。
昨日お気楽会議室で質問した答えが返ってこない。
詳しく分かる人がいないのか。暫らく様子を見てまた別の場所で聞いてみるとしよう。
ついでにお気楽会議室のほかの人の質問を見てみると
意外と分かる事が多かった。
ちょっと前までは分からない事ばかりだったのに大した進歩だ。
レスがまだ付いていない質問で分かるものがあったから
答えを書いて更新すると2人も同じ事を書いてかぶっていた。
たった4分の間に・・・。でも良く見ると僕の答えだけが少し違う。
一応間違ってはいないが他の人の答えの方が簡単だった。
まだまだ勉強が足りないね。
1月15日 opt:nowin98
この前スクリーンセーバーのソースを探している時に
とあるHPに書いてあった実行ファイルのサイズを小さくする方法を試してみた。
が、全然小さくならない。やはりMFCを使っていてはダメか。
そのHPでもAPI以外は使うなって書いてあったしな。
しかしもう1つの方法でVC++6.0ならリンクオプションに /opt:nowin98 を追加すると
小さくなるらしく試してみた所見事に小さくなった。といっても10KB程度だが。
でもMFCでスタティックライブラリを使わなければ効果は結構大きい。
適当なサンプルで試してみたら20KBから6KBまで小さくなった。
何故小さくなるかと言うとファイルのアライメントを以前の方法に戻すらしいが
この意味がさっぱり分からない。
VC++6.0でコンパイルするとそれ以前のバージョンよりも大きくなる事は知っていたが
それを元に戻したと言う事だろうか。
だとすると何か問題は起こらないか不安だ。
とりあえずお気楽会議室で質問しておこう。
1月14日 配列
ぐるぐるはビットマップを連続して表示するやり方で一応基礎は出来た。
連続で切り替えると画面がちらつくかと思っていたが全く問題なし。
18枚のビットマップを読みこむのに最初は1つづつロードし切り替えていたが
もしかしてと思いリソースのIDをよく見てみたら連続しているじゃないか。
さらにクラスの宣言で[x]を使ってみたら、これまた上手く行った。
おかげでforステートメントでまわしてやる事ができ、かなりコードが短くなった。
うんうん、これはテクニックだね。MFCのサンプルソースのコーナーにも乗っけておこう。
しかしビットマップを18枚もリソースで組みこんだから実行サイズがでかい。
最初は5MBにもなってしまった(爆)
とりあえずビットマップを24ビットからモノクロに変えた事で500KBほどになったが
まだまだデカイ。一応圧縮すれば150KBまで落ちるんだけどね。
他にもやらなければならない事が結構ある。もうチョイ公開は先になるかな。
1月13日 復活
昨日医者で点滴打って安静にしてたおかげで1晩で何とか復活。
でも今日はまだおとなしくしてた方が良いだろうから1日中バクスイ。
僕の場合下手に風引くとマジヤバだからね。
去年・一昨年はそれで入院しちゃったからな〜。
1月12日 風邪
風邪引いた。最悪。気持ち悪い。
コタツで寝るとこうなるって分かっていたんだけどついつい・・・。
あーあ、マジ気持ちわる。
1月11日 MFCとSDK
MFCのソースが見つからなかったからscrnsave.libをちょこっと調べてみたが
こいつは良いぞ。スクリーンセーバー作るにはもってこいじゃないか。
最初からパスワードもサポートしてるし言う事なし。
でもMFCが使えない・・・。つまりSDKでコードを書かないとダメなんだよな。
とりあえずプログラム組んでみようと思ったけどさっぱり分かんないや。
ヘルプ見ても英語ばっかりだし。
よくMFCはタコだとか腐っているとかSDK使える人は言うけど、
MFCも実際便利だぞ。これが無いと僕は何もできん。
確かにSDKは無駄が無くて速いし、プログラムサイズも小さくなるけど
それだけ何でもかんでも自分でやらなきゃダメだってことだし、
初心者には分かりづらい。ペルプは半分英語だし。(重要)
一つのウィンドウを表示させるだけで何10行もコード書くのは辛すぎる。
MFCなら一発で出来るのに。(でも実際は内部で数100行は書いてるんだろうな〜、
そこがタコとか言われる由縁なんだろうけど・・・。)
何にせよMFCが無くなると困る人はごまんと出てくるだろうから
MFCなんか無くしてしまえって言うのは言いすぎだと思うな。
僕的にはCの速さとVBとかの高級言語の簡単さを併せ持ったライブラリだと思うけどね。
無論言い換えればCの良い所を殺しVBよりも難しいって事にもなるんだけどさ。。。
結局scrnsave.libは諦めてもう一回MFCのソースを探してみた。
インフォシークで検索しなおしたら何と19番目に目的のものが・・・。
昨日あれだけ探して見つからなかったのに・・・。
同じキーワードで検索したんだけどなぁ、思いっきり見過ごしてた。
なんか無駄な1日を使ってしまった感じ。
1月10日 スクリーンセーバーのソース
HPの更新も終わり一段落したので前々から作ろうと思っていた
スクリーンセーバーを作る事にした。
名前は「グルグル」で行くつもりだったけどよく考えたら
「ポストペットチェンジ」「カメレオン君」とカタカナ続きだったので
「ぐるぐる」と平仮名にした。<あんま変らないけどさ。
基礎はカメレオンと同じようにやれば良いので特に問題無く出来ていった。
後は設定画面とスクリーンセーバーの画面を作るだけ。
設定画面は大した事は無いから後回しで良いとして
問題はスクリーンセーバーの画面。
要はビットマップを連続して表示してやれば良いのだがこれは初の試み。
今までビットマップを扱った事は一度も無い。
でも前に手に入れたスクリーンセーバーのサンプルソースが
似たような処理をしているのでそれを参考にすれば簡単に出来ると思っていた。
が、そのファイルを見てみると肝心な部分がカメレオンのコードに書き換わっている。
どうやらカメレオンを作っていたとき試験的に書き換えたものを間違えて保存したらしい。
ソースのバックアップは取ってあったのだがこの前ふとした事で消してしまっていた。
「オーマイガッ!」など言ってても仕方がないからまたもう一度DLしてこよう・・・。
と思ったけど何処で手に入れたか忘れた。
確か検索エンジンで見つけたはずだけどいくら探しても出てこない。
他のスクリーンセーバーのサンプルでも良いのだがそれすら出てこない。
やはりMFCでスクリーンセーバーを作るのは一般的じゃないのかな。
scrnsave.lidを使ったサンプルなら見つかったがSDKはいまいち分からん。
結局朝までサンプルソースを探したけど見つからず。
カメレオンのソースも一応近いものがあるからそれで何とかしよう・・・。
1月9日 ファイル入出力
MFCのサンプルで1つ追加するのを忘れていたのでそれを書こうとした。
それはテキストファイルから1行ずつ読み込むコードで
サンプルになるように関数形式に手直ししようとした。
しかし上手くいかない。fopenで開いたファイルのポインタの渡し方がさっぱり。
さらにこのサンプルはMFCを使わずCだけで書いていたので
returnでファイルから読み込んだ文字列を返す事も出来ない。
MFCならCString型で関数を定義すれば簡単だけど
Cだからchar型で定義し返そうとしたら思いっきりエラー。
ビルドできればデバッグも出来るけどそれすら出来ない。
もうチンプンカンプンだから久しぶりに基本に戻ってC++教育のHPを見直した。
が、載っていない。いや、書いてあるかもしれないが理解できない。
ポインタも調べてみたがchar型についての記述は基本しか書いていない。
いろいろ調べていたらもっとショックな出来事が。
ファイルから1行ずつ読み込む関数が存在していた。
istream::getline()・・・。
結局このサンプルソースはお蔵入りにする事にした。
ちなみにistream::getline()での読み込み方。
MFCを使わずコンソールC++なのでサンプルソースには加えないとく。
// ファイルから1行ずつ読み込む #include <iostream.h> #include <fstream.h> #include <conio.h> void main() { char pch[100]; char file_name[32]; cout << "ファイル名==>"; cin >> file_name; ifstream MyFile(file_name); while(MyFile.getline(pch,100)) { cout << pch << " hit any key" << endl; getch(); } }
1月8日 窓の杜
HPのアクセス数が昨日1日で793も増えていた。
いきなりの増え方で一体何処から来ているかリファラーを調べてみたら
窓の杜からのアクセスらしく逆リンクを辿ってみると
窓の杜の新着情報にポストペットチェンジがVerUPしたと書いてあった。
あそこに書かれるだけでこんなにもアクセスが増えるとは。
窓の杜のアクセス数ってものすごく多いんだろうな。
前にアクセスが急増した事があったけどその時もここに紹介されたのだろうか。
カウンターのログを見てみると10月29日。その頃の開発記を見てみたら
2日前にポスペチェンジャーをVerUPしていた。
やっぱり前回の急増も窓の杜の仕業だね。
今回は元旦にVerUPしたから新着情報も休みで紹介が遅れたのだろう。
新着情報では6日遅れになっていた。
ところでカメレオンも一緒にVerUPしたのに紹介されていない。
なんだか寂しい。僕的にはカメレオンの方が好きなのにさ。
窓の杜も見る目が無いね〜。
1月7日 フォント
インフォメーションのボードを作っている時気が付いたんだけど
HTMLでフォントをMS ゴシックを指定してもブラウザで見ると等幅になってない。
半角数字はどうも固定らしい。
おまけにネスケで見てみたらフォントが違う。
ネスケでフォント設定は無駄らしい。
このHPはネスケはサポートしてないけど一応見れるようにはしてある。
でもここまでレイアウトが違うのはいただけない。
<PRE>タグを使ってみたらネスケも固定フォントになったからそれを採用したが
やっぱり半角数字は大きさが変ってくる。
仕方がないから<TABLE>タグで整理したがこういうのあんまり好きじゃないんだよな。
1月6日 インフォメーション
今日は雑誌の紹介履歴やお知らせみたいなことを書いてあるボードを作る事にした。
とりあえず名前はインフォメーションでいいかな。
場所はDounLoadのページにしようかと思ったけどトップの方が見やすいか。
新しくページを作る必要も無いでしょう。
細かい事は明日やろ。
1月5日 サンプルソース
HPの更新のためのMFCサンプルソースを2つだけ追加。
今ソースはだいぶ前に使ったものだったので使い方を忘れてしまっていた。
それでも何とかもう一度調べて書いたが、ま、こんなものでしょ。
1月4日 更新
ここの所HPの更新を全然していなかったからちょと更新する事にした。
とりあえずMFCのサンプルソースで書いておきたい事があるからそれを増やして
後はリンクにDownloadASCIIへのリンクを追加しておかなきゃ。
そう言えばここにもポスペチェンジャー登録していたんだっけ。ここも更新しなきゃな。
あ、ベクターも全然更新してないや。とりあえずここは今日中にやっておこ。
DownloadASCII の更新の仕方はどうだったっけな。
ま、いいか。明日調べてみるとするか。
1月3日 カルチャーショック
今日はオフ会で浜松まで行ったんだけど、そこでこっちの方では考えられない事が。
「何でカラオケBOXの料金が一人当たり1時間いくらなんだ?」
普通1室1時間いくらでしょう。カラオケBOXは。
そうじゃないと大人数で行った時、歌う順番はなかなか回ってこないわ
料金は高くつくわで大損じゃないか。納得いかね〜。
それからもう1つ。これは浜松じゃなくて帰る途中の安城市あたりでの事なんだけど
「なんでDDRが100円でしかも5ステージまであるの?」
普通200円で3ステージ若しくは4ステージでしょ。
帰りあんまり眠かったからちょこっと寄ったドライブイン(一般道)でDDRを見つけ
眠気覚ましのつもりでやったDDRだったけど、余計ヘロヘロに。
その時は確かに眠気は覚めたけどその後急に睡魔が・・・。
危ない危ない。
1月2日 アクセスログの不具合
ちょっと前にK−NETのアクセスログを設置したが上手い具合に動いていなかった。
自分がアクセスした記録は残るのに他の人の記録は余りカウントされていない。
ブラウザの問題かと思ったけどIE4.0やネスケでもカウントされている事がある。
何故だか不思議だったけどジオのページを見て原因が判明。
アクセスログを呼び出すためのCGIへのリンクが相対リンクになっていた。
このためジオのページへのカウントが記録されていなかったみたいだ。
どうりで自分の記録は残るのに(モモの方でテストしていた)
他の人の記録は余り残らないわけだ。(モモの分しか)
オオボケだったね。
1月1日 A HAPPY NEW YEAR!!
明けましておめでとう記念、カメレオン&ポスペチェンジャーのVerUP完了。
予定よりもはやくReadme.txtの書き換え等が終わったから朝のうちにHPにアップした。
ついでにフリッポの登録も更新してきたが、フリッポの登録が更新されるのは
暫らく後みたいで夜DLカウントを見てみたら案の定狂っていた。
ちょっと困りものだね、あれは。