ラベル Windows の投稿を表示しています。 すべての投稿を表示
ラベル Windows の投稿を表示しています。 すべての投稿を表示

11.30.2009

思い立ったらすぐやってみる派。

Objective-CでWindowsアプリな回で予想したとおり、SDL試してみました。

MinGW向けのSDLライブラリを、公式サイトからゲット。

で、ここを参考にコードを書く。
しばらく触ってなかったせいか、SDLの流儀的なものをすっかり忘れている。
チュートリアルサイトのコードがないと書けないとか、一時期SDLに取り組んでたとは思えない低能っぷり。実に恥ずかしいな。

#import <SDL/SDL.h>
#import <stdio.h>
#import <objc/Object.h>

#define SCR_WIDTH 640
#define SCR_HEIGHT 480
#define SCR_BPP 32
#define CAPTION "SDL Hello"

SDL_Surface *gScreen;

@interface Game : Object
- (BOOL)Initialize;
- (void)End;
- (BOOL)PollEvent;
@end

@implementation Game
-(BOOL) Initialize {
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) return NO;

SDL_WM_SetCaption( CAPTION, NULL );
gScreen = SDL_SetVideoMode(
SCR_WIDTH,
SCR_HEIGHT,
SCR_BPP,
SDL_SWSURFACE);

SDL_ShowCursor( SDL_DISABLE );
return YES;
}

-(void) End {
SDL_Quit();
}

-(BOOL) PollEvent {
SDL_Event ev;
SDLKey *key;

while(SDL_PollEvent(&ev)) {
switch(ev.type) {
case SDL_QUIT:
return NO;
break;
case SDL_KEYDOWN: {
key = &(ev.key.keysym.sym);
if( *key == 22 ) {
return NO;
}
}
break;
}
}
return YES;
}
@end

int main(int argc, char* argv[])
{
id G = [Game new];

if( ![G Initialize] ) {
printf("Initialized fail.\n");
[G free];
return 1;
}

while( 1 ) {
if( ![G PollEvent] ) break;
}

[G End];
[Game free];
return 0;
}


全然Objective-Cっぽくないという。
まぁ、Objective-Cの機能を使ったコードが通るってことを実証したかったわけで。

最初、BOOL型をboolとして怒られ、YESをtrueやTRUEとして怒られ、NOをfalseやFALSEとして怒られた。
文化の違いってやつだと思う。Booleanなのに、真偽じゃなく、YES/NOって……。
(どうでもいいけど、Accessだったっけか?YES/NO型ってのがあるの。)

ともかく、ざっくりと上記のようなコードを書き上げて、

gcc [filename] -lobjc -lmingw32 -lSDLmain -lSDL -mwindows

とかしてコンパイルしてやる。
もちろん、手元では-lobjcじゃ通らないから、直接ライブラリファイルを指定してるわけだけど、パスを書くのが面倒だから、ここでは-lobjcで代用しとく。

当然?とでも言うかのように、エラーも警告無くコンパイルが通って、exeファイルが生成される。
必要なDLLがそろってるディレクトリに移動させて、起動してやると、図のようなウィンドウが出た。



うん。OKなんじゃない?
もっとうまく、オブジェクト指向なコーディングが出来れば、なお使いやすそう。
お遊びに使うには十分すぎる性能を持っていると言えるカモね。

11.28.2009

Objective-CでWindowsアプリを作ってみる。

そんなわけで、Objective-Cな環境の導入に成功したので、

#import <windows.h>
#import <objc/Object.h>

@interface SayHello : Object
- (void) Hello;
@end;

@implementation SayHello
- (void) Hello
{
MessageBox( NULL, "HELLO WORLD", "MESSAGE", MB_OK);
}
@end;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd)
{
id obj = [SayHello new];
[ obj Hello ];
[ obj free];
return 0;
}

とかいうプログラムをこさえてみた。

要はCと親和性が良いというなら、Cから使えるWin32APIだって呼べるんじゃねぇの?という発想。

コマンドラインから
$gcc objcwin.m C:\mingw\lib\gcc\mingw32\4.4.0\libobjc.a -mwindows

とかして、-mwindowsオプションをつけてMinGW-gccでコンパイルをかけてやると、アッサリ通った。
MessageBox程度だけど、すんなり行けちゃった事にオドロキを覚えた。

この調子なら、SDLあたりもいけそうかな。また今度試してみようと思う。
で、せっかくならこれを生かしてマルチプラットフォームなGUIアプリでも組めたら、さぞ面白いだろうと思ったんだけど、Cで実装されてるGUIライブラリで有名なものって、私の大嫌いなGtk+ぐらいしかないのね。

う~ん。となると、Objective-Cはお遊び用かなぁ。
C++と混在できれば、wxWidgetとか使えるんだろうけどな。
その辺も調べてみようと思いまつ。

11.22.2009

MinGWでObjective-Cを試してみる。

ちょっくらObjective-Cに興味があって、前々から調べていたんだけれども、この休みに……と思って、MinGW環境でObjective-Cを試してみた。

なんでわざわざMinGWを使う買って言うと、Linux環境では既に成功しているから。
せっかくだし、Windows環境でも動いたら嬉しいなと思ったのだ。

まずはMinGWの公式サイトにいって、アーカイブをもらってくる。
ここで注意しないといけないのは、普通に配ってるインストーラを使っての導入だと、gccのバージョンが3.x系になってしまうこと。
だから、Getting Startedにあるようにマニュアルインストールを行う。

リストに上がっている
binutils
mingw-runtime (dev and dll)
w32api
Required runtime libraries for GCC (gmp, libiconv, MPFR and pthreads)
gcc-core (bin and dll)

のほか、

gcc-objc (bin and dll) for Objective C

と

mingw-gdb for debugger
mingw32-make for make
mingw-utils for MinGW Utilities

総勢15のファイルを取ってきて、C:\MinGWフォルダ以下に展開しておく。
解凍には7-zipというフリーソフトを用いた。スゲー便利。

で、起動用バッチファイルを用意。
環境変数を直接いじってもいいんだけれども、なんとなく今回はバッチファイルを使うことにした。
mingw.cmdとかいう名前で、C:\MinGW直下に保存。
内容は今のところ
@echo off
set PATH=%PATH%;C:\mingw\bin
set INCLUDE_PATH=C:\mingw\include;C:\mingw\lib\gcc\mingw32\4.4.0\include
set LIBRARY_PATH=C:\mingw\lib;C:\mingw\lib\gcc\mingw32\4.4.0
set LIBPATH=C:\mingw\lib;C:\mingw\lib\gcc\mingw32\4.4.0
set LD_LIBRARY_PATH=C:\mingw\lib;C:\mingw\lib\gcc\mingw32\4.4.0
set TEMP=C:\TMP
set TMP=C:\TMP
set LANG=C
cd C:\mingw\src
@echo on

な感じ。まだ試行錯誤中なので、今後変わる可能性大。
ちなみに、最後のcdコマンドは作業ディレクトリに移動するためのコマンド。
C:\workで作業するならそれに書き換えてあげると楽。

で、ここまで出来たら、デスクトップにコマンドプロンプトのショートカットを作って、プロパティから、リンク先を
%SystemRoot%\system32\cmd.exe /k "C:\mingw\mingw"

とかしてあげる。

これができたら、そのショートカットからコマンドプロンプトを起動して、
$ gcc --version

でgccのインストールを確認する。

次に、Objective-CでHello worldを書く。
例えばhello.mの内容を
#import < stdio.h >
#import < objc/object.h >

@interface Test : Object
- (void)Hello;
@end

@implementation Test
- (void)Hello {
 printf("Hello Objective-C World\n");
}
@end

int main() {
 id obj = [Test alloc];
 [obj Hello];
 
 return 0;
}

とかしてあげる。たぶん、allocしたのにfreeしてないとか、ツッコミどころはあるんだろうけど、ネットで適当に拾ってきたソースの改変かつコンパイルのテストなので、そこは目をつむっておく。

これができたら、先ほどのコマンドプロンプトに戻り
$ gcc -lobjc hello.m

とかする。通常は、これでうまくいくらしい。
通常はと書いたのは、ウチでは以下のエラーを吐いて、コンパイル(正確にはリンク)がコケてしまったからだ。

C:\TMP\cczsTv17.o:hello.m:(.text+0x24): undefined reference to `objc_msg_lookup_
super'
C:\TMP\cczsTv17.o:hello.m:(.text+0x69): undefined reference to `objc_get_class'
C:\TMP\cczsTv17.o:hello.m:(.text+0x7c): undefined reference to `objc_msg_lookup'

C:\TMP\cczsTv17.o:hello.m:(.text+0x9d): undefined reference to `objc_msg_lookup'

C:\TMP\cczsTv17.o:hello.m:(.text+0xc4): undefined reference to `objc_msg_lookup'

C:\TMP\cczsTv17.o:hello.m:(.text+0xe7): undefined reference to `objc_msg_lookup'

C:\TMP\cczsTv17.o:hello.m:(.text+0x112): undefined reference to `__objc_exec_cla
ss'
C:\TMP\cczsTv17.o:hello.m:(.data+0x140): undefined reference to `__objc_class_na
me_Object'
collect2: ld returned 1 exit status


ネットを探しても、さしたる情報は出てこない。
ldでコケてるのは間違いないから、LD_LIBRARY_PATHとかを環境変数に追加してみたものの、一向にエラーは消えない。

Linuxなら、/etc/ld.so.confに代表される、ldの設定ファイルいじるとか(そもそもLD_LIBRARY_PATHがあるのに通らないのが変なんだけど)できるけど、Windowsはよく分からないのでお手上げ状態。

で、結局解決策として
$ gcc hello.m C:\mingw\lib\gcc\mingw32\4.4.0\libobjc.a

という、直接ライブラリを指定してリンクさせる方法を取った。
たぶん、作法的には汚いやり方なんだろうけど、他に解決策が思いつかないのだから仕方ない。
どなたか、このldのエラーについて解決策を知っていたら、ぜひとも知らせて欲しいデス。切実に。

他に同じエラーで困っている人が居たら、一応の解決策として上記みたいなことができるよってことで、メモ代わりにエントリを挙げときます。

10.09.2008

IME 2007 が遅くてお困りの方へ。

いやー。
めちゃめちゃ悩んでました。
IME 2007 がとにかく遅い。

日本語を打とうと、IMEを起動させようとすると、これがなかなか起動してくれない。
まさにナゼ???
な状態に陥っていたわけですよ。

んで、いろいろ探してたら、
猿頁(10) http://salv.miscnotes.com/2007/02/ime2007.php
にてまさしくこれだ!という方法を発見。

それは、
「Outlook関連の辞書を削除する」
ということ。(大事なことなので強調しました。)

どういう仕組みなの?は先のページに譲るとして
ここではやり方をば。

0.IME 2007の言語バーをタスクバーに入れている人は、それを復元します。
1.[ツール]→[プロパティ]とたどります。(ツールは工具箱みたいなアイコン)
2・あとは、[辞書/学習]タブの下部、システム辞書から、Outlook~な項目を[削除]すればOK。

ここで重要なのは、Outlookを標準のメーラーとして使っている人は、これをしない方がいいということ。
なぜ??と思った人は、先のページを見てください。

所詮ノウハウのなぐり書きなので、うまくいかなくても知りませんし、何かトラブルがあっても知りません。
それでもイイ!という方は、試してみると幸せになるかも。

ちなみに、私は幸せになれました。(←情報商材のキャッチフレーズみたいだな(笑))

# 追記:
IMEブログもみておくべし!

8.08.2008

MinGWで自作プログラムにアイコンを付与する方法

15パズルなんですが、うまいぐあいの判定関数&パズル生成関数が思い浮かばなくて、結局ちょこちょこと内部をリファクタリングしただけで、ニコニコを見てしまうという悪循環に(以下略

さて、そんな中で、MinGWでプログラムにアイコンを設定できないものかと思い立ち、ちょろっと探してやってみました。
(すでにダウンロードできる15パズルのファイルは差し替わっています)

ちなみに、(SDLとあわせているせいかもしれませんが)ウィンドウ左上のミニアイコンにはリソースからの設定ができていません。
たぶん、ゲームプログラムならフルスクリーンだったり、左上アイコンにはこだわらないだろうから問題ないんでしょうけど。

一番簡単なのは、
101 ICON "iconfilename.ico"
なんてのを適当なテキストエディタで作成して、resource.rcか何かのファイル名で保存しておきます。

次に、windres(今回私が相手にしているクロスコンパイル環境においては、i586~という長い名前だったので、適当にlnしておきましたよ。)を使って、
$ windres -o resource.o resource.rc
とすると、resource.oというオブジェクトファイルが生成できます。

あとはこれをコンパイル時に渡してあげればOK。
具体的には
$ mingw-cc filename.c resource.o
でいけるはず。
私はリソースIDを101にしたんだけれども、(リソースファイル内にほかのアイコンが無いせいかもしれないが)勝手にデフォルトアイコンとして付与されたから、よっぽど変なことしてない限り、これでいけるんじゃなかろうかと。

よし。今度こそ続きは帰ってきてからやろう。

# 何かいい判定関数/生成関数のアイディアをお持ちでしたら、教えてください。


以下、参考サイト(順不同)
http://www.sixnine.net/cygwin/translation/cygwin-ug-net/windres.html
http://www.m-oz.com/soft/mingw.html
http://www.arcpit.co.jp/winapi/api_01/ap010312.htm

3.03.2008

WindowsXPでジャンクション機能を手軽に使う。

@ITでは、リソースキットを使ってジャンクション云々って、読むのもアレな記事をTipsとして紹介しているけど、きっとここに書いてある内容と同じようなことなら、リンク作成シェル拡張ってソフトを使うことで、簡単に実現できると思う。

エクスプローラに統合されて、右クリックメニューから簡単に呼び出せるのもポイント高いしね。
私の場合、C:\ドライブ直下に適当なディレクトリ(workとか、そんな名前の)を作って、それをマイドキュメントとかにリンクしている。

んで、欧米のいわゆる「日本語を扱えない」アプリケーションを利用する時に、このディレクトリを指定して、擬似的に日本語のフォルダ名を扱えるようにしてる。(マイドキュメント→workのようになる)

これが結構便利で、例えばcoLinuxのcofsを使うときにも、パスが短くなるし、普段Windowsで良く使うフォルダにリンクさせておけば、Linux⇔Windows間の連携も驚くほどスムーズにいく。

ちなみに、手元で試した限りでは、GnuWin32に含まれるlnコマンドでも同様にリンクを貼れる。
このとき、-sオプションを指定してリンクさせるとショートカットの作成になるから、コマンドラインで作業したい人には便利かもしれない。

忘れがちだけど、こういうところでNTFSはPOSIXを取り入れていることを思い知らされるんだろうなぁ。