Knowledge | ||||||
WideStudioプログラミング
2004/02/17 |
WideStudioで「Hello」
| ||||
2004/02/24 |
| ||||
2004/03/04 |
WideStudioでスプラッシュ! せっかくなので、オンラインマニュアルを読めばわかることはおいといて、ポイントを紹介させていただきます。 作ったものは…起動すると、メインのウィンドウ以外にもう1つ、起動表示用のビットマップを貼ったウィンドウを開き、1.5秒後に自動的に閉じるものです。よくアプリケーションでありますよね?起動するときに製品名とか表示されて、後ろでアプリケーションが起動処理をするやつ。アレです。いまのところ、これだ!という方法が良くわからないので、スプラッシュ風っていうのが正解なんでしょうか? こんなふうに作ってみました。まずはアプリケーソンビルダを使います。
こうやって考えてみると、実は、タイマのスタートって、INITIALIZEでかけてるのってまずいのかな?スプラッシュなので、構わないって感じですけど。ウィンドウが開いてからカウント開始するのが正しそうなので、別のトリガがいいのかもしれません。というわけで、さっそく「EXPOSE」に変えてみました。これは描画された時に発生するトリガです。「ウィンドウ表示=最初の描画が行われる→EXPOSEが発生する」と思いまして。このあたり、アプリケーションビルダでやると、めちゃ簡単です。マウスでちょいちょい。んで「実行」…あ、いい感じですね。スプラッシュの時はどっちでもいいんでしょうが、普通の時はこの方が良さそうです。 というわけでわかったこと。
相変わらず、プロシージャの「プロシージャ名称」の意味がわからず、適当に名前付けていたりします。お作法は、今日の分に関してはだいぶわかってきたのですが、依然、やりたいことについてはわかっていないです。 ONO様…本の読破ですが、最初は「うっ」っと思いました。でも、最初…斜め読み、2回目は割とまじめ、後は必要に応じて、と読んでいたら、結構、楽しく読めましたよ。個人的には、もうちょっと仙人の会話が欲しかったです。すべてはわかりませんが、とっかかりと、大雑把な概念を理解するのであれば、なかなか良い本だと思います。 それにしても、ここはどこだ?日本語が通じないぞ?というわけで、これから数日は、WideStudioネタになるかな(笑)。 ではでは! | ||||
2004/03/12 |
うぅ、相変わらず出先のSISOです(しかも、いつもに増して忙しい)。トランジスタ技術(H8のおまけ付き)は、友人にメールして買ってもらいました(3冊程)。たぶん、シリアル通信のレベルコンバータは買わないといけなさそうです(って、買った人はきっと、もう確認されてますよね〜)。そういえば、GOLDENWORKSさんのところで、基板で売っているUSB-SERIALコンバータが紹介されていましたが、あれに一緒に組み込んじゃって、マイコンアクセス専用にしちゃってもよさそうですね〜。んで、ついでにUSBから5V取り出してマイコンに供給したらモバイルですね!電車の中でも、飛行機の中でもマイコンソフトを開発できそうです。今度やってみよう。 WideStudioでメニュー
■ALT+Fでメニューが開かない…うぅ、マニュアル読みなさいって感じ。
■メニューに関連付けた実行関数が呼び出せない…うぅ、やっぱりマニュアル(以下略) | ||||
2004/03/16 |
WideStudioでスライドバー、しかも動的生成 画像で見ると、「トグルスイッチ」、「ラベル」、「スライドバー」という3つの部品で構成されている塊が、4つ表示されているのがわかると思います。これらは、アプリケーションビルダで作ったのではなく、プログラムにて動的に生成しており、スライドバーを動かすとその値がラベルに反映されるようになっています。さてさて、どうやって作ったかを解説してみたいと思います。いつもながら思うのですが、わかっている人には「しょうもないコード」です。でも、これもまたワタクシメの歴史なので、笑って許してください。 ■まずはインクルードファイルとその他準備 #include <WSCvtoggle.h> #include <WSCvlabel.h> #include <WSCvslider.h> 次に、トグルスイッチなどを生成した時に、実体を管理するためのポインタ配列を作ります。管理する対象は、「トグル」、「ラベル」、「スライダ」ですので、それぞれのクラスのポインタ配列とします。また、「何個管理する」といった情報は、あちこちで使いますので、#defineしておきます。そんなわけで、上記の#includeにつづいて、以下のようなソースを書きます。 #define NUM_MAX 4 WSCvtoggle* STM_aptglServoPls[NUM_MAX]; WSCvlabel* STM_aplblServoDeg[NUM_MAX]; WSCvslider* STM_apsldServoDeg[NUM_MAX]; まあ、こんな風に、いきなりグローバルにするとかっていうのは、なんとなく気が引けますが、他のサンプルとかを見ている限りではよさそう(WideStudioの中では悪くない?)な気がしますので、よしとします。相変わらず、お作法がつかめていませんが、こんな感じでしょう。余談ですが、イメージ的には、「C++クラスライブラリをベースとして、それをCでお気軽に呼び出して使う世界」な気がします。とても現実的で、とっかかりがいい感じですが、本当のところはどうなんでしょう? ■INITIALIZEの実行関数に生成機能を組み込む!(とりあえず) int nCnt; char szServoName[64]; for( nCnt = 0; nCnt < NUM_MAX; nCnt++ ){ sprintf( szServoName, "SERVO-%02d", nCnt ); // ここからいろいろ書き足します。 } ■部品の動的生成 STM_aptglServoPls[nCnt] = new WSCvtoggle( object, szServoName ); STM_aptglServoPls[nCnt]->initialize(); このあたりは、サンプルソースを見て、「う〜ん、こうかなぁ」とやってみました。本を読むと「生成したらとにかくinitialize()」と、非常に楽しい文章で説明されています。さらに、WSCvtoggleのnewする時のパラメータ、まだよくわかっていません。どっかに少しだけ書いてあったような気がするのですが、1つめは親となるオブジェクト、2つめは「名称」だと思います。だとすると、1つずつ、名前を変えないといけないような気もするのですが、動的に生成する場合は、問題にならないようです(アプリケーションビルダでは、ソースを自動生成する都合上のものかな)。 そして、WSNuserValueを設定します。一見、何につかえるかわからないプロパティですが、ここに数値を入れておくと、後で取り出して使うことができます。イベントプロシージャの実行関数を1つで書いてしまう場合、この数値を使って識別をさせることができますので、ちゃんと数値を設定することにします。 STM_aptglServoPls[nCnt]->setProperty( WSNuserValue, nCnt ); 後は表示名です。このプロパティに設定した文字列が、トグルスイッチのところに表示されます。 STM_aptglServoPls[nCnt]->setProperty( WSNlabelString, szServoName ); 最後に、表示サイズや表示位置を設定します。ループにあわせて、Y座標がずれるようにしてあります。このあたりは趣味の問題なので、好きなように設定すればよいと思います。どれがどの値かは、アプリケーションビルダで試しに1つ部品を作ってみて、プロパティでいじくって確認してみてください。 STM_aptglServoPls[nCnt]->setProperty( WSNx, 0); STM_aptglServoPls[nCnt]->setProperty( WSNy, nCnt*40 ); STM_aptglServoPls[nCnt]->setProperty( WSNwidth, 100 ); STM_aptglServoPls[nCnt]->setProperty( WSNheight, 18); STM_aptglServoPls[nCnt]->setProperty( WSNindicatorSize, 16 ); STM_aptglServoPls[nCnt]->setProperty( WSNshadowThickness, 0 ); おっと。最後の最後に、「表示!」します。 STM_aptglServoPls[nCnt]->setVisible(True); 同様に、ラベル、スライダも設定します。設定しているのは表示系ばかりですので、それぞれのプロパティについては、アプリケーションビルダで1つ作ってみて、確認してください。というわけで、以下のようになりました。 STM_aplblServoDeg[nCnt] = new WSCvlabel( object, szServoName ); STM_aplblServoDeg[nCnt]->initialize(); STM_aplblServoDeg[nCnt]->setProperty( WSNuserValue, nCnt ); STM_aplblServoDeg[nCnt]->setProperty( WSNlabelString, "0" ); STM_aplblServoDeg[nCnt]->setProperty( WSNx, 100 ); STM_aplblServoDeg[nCnt]->setProperty( WSNy, nCnt*40 ); STM_aplblServoDeg[nCnt]->setProperty( WSNwidth, 50 ); STM_aplblServoDeg[nCnt]->setProperty( WSNheight, 18); STM_aplblServoDeg[nCnt]->setProperty( WSNshadowThickness, 0); STM_aplblServoDeg[nCnt]->setVisible(True); STM_apsldServoDeg[nCnt] = new WSCvslider( object, szServoName ); STM_apsldServoDeg[nCnt]->initialize(); STM_apsldServoDeg[nCnt]->setProperty( WSNuserValue, nCnt ); STM_apsldServoDeg[nCnt]->setProperty( WSNx, 0 ); STM_apsldServoDeg[nCnt]->setProperty( WSNy, nCnt*40+18 ); STM_apsldServoDeg[nCnt]->setProperty( WSNwidth, 150 ); STM_apsldServoDeg[nCnt]->setProperty( WSNheight, 18); STM_apsldServoDeg[nCnt]->setProperty( WSNsliderSize, 16 ); STM_apsldServoDeg[nCnt]->setProperty( WSNmaximum, 127 ); STM_apsldServoDeg[nCnt]->setProperty( WSNminimum, -127); STM_apsldServoDeg[nCnt]->setProperty( WSNdragInterval, 1 ); STM_apsldServoDeg[nCnt]->setProperty( WSNvalue, 0 ); STM_apsldServoDeg[nCnt]->setVisible(True); ■イベントプロシージャの割り当て まずは、実行関数の方です。割と一般的で、普通のスライダサンプルプログラムもこんな感じだと思います。 void STM_opeSlideServoDeg( WSCbase* object ) { char szDeg[64]; int nIdx, nDeg; nDeg = object->getProperty( WSNvalue ); sprintf( szDeg, "%d", nDeg ); nIdx = object->getProperty(WSNuserValue); STM_aplblServoDeg[nIdx]->setProperty( WSNlabelString, szDeg ); } 中身は簡単なものですが、先に説明しましたWSNuserValueが活躍しているのがわかると思います。この実行関数は、すべてのスライダから呼び出されます。そのため、どの人から呼び出されたかを認識しないといけないです。この行です。 nDeg = object->getProperty( WSNvalue ); この実行関数が呼び出されるとき、objectという変数が渡されますが、これが、この関数を呼び出したオブジェクト(このケースの場合、具体的にはスライダのオブジェクトの1つ)のポインタになります。先の初期化で、WSNvalueに、固有の識別番号を入れていますので、これを取り出すことによってどのスライダから呼び出されたかがわかります。 よって、どのラベルを更新するかわかることになりますね! さて、この実行関数を、WSEV_VALUE_CHイベントが発生した時に呼び出されるように、生成したスライダオブジェクトに割り当てます。それには、以下のように、プロシージャを名称とトリガから生成、生成したプロシージャに実行関数を割り当て、そしてスライダにこれを追加するという形になります。 WSCprocedure* ep = new WSCprocedure( "SERVO_DEG", WSEV_VALUE_CH ); ep->setFunction( STM_opeSlideServoDeg, "STM_opeSlideServoDeg" ); STM_apsldServoDeg[nCnt]->addProcedure( ep ); これをforループの、スライダを生成した後に実行するようにすればOKです。これで「スライダを動かすとラベルの値が変わる」という部品を、動的に生成することができるようになりました。それぞれの部品の表示位置や制御対象とするサーボの情報などを、定義ファイルとかで与えて、SIPHA-COREと通信できるようにすれば…うふっ。
| ||||
2004/03/21 |
相変わらず異国の地のSISOです。ああ、思えば、ROBO-ONEが終わって約2ヶ月。ほとんどこんな生活をしております。しかも、先日、熱がでて寝込んでしまいました。こっちのメンバーにヘルプしてもらって初めて異国の病院に行きました。行ってみたら、全然日本と変わりませんでした。もっと早く行けばよかった。診断結果はただの風邪でした。今は、微妙にフラフラする気もしますが、久しぶりにたくさん寝ているので、そのせいかもしれません。というわけで、時間を見つけてWideStudioです。 なぜ、今、WideStudioか?それはですね、「仕事のおかげでロボットに触れない」→「時間が無い」→「いじける」→「引きこもる」…ではつまらないので、時間が無いのならば、時間をかけずに完成できるよう、開発環境を整えておく!という、非常に前向きなような、そうでないような、しょうがないからそうしているような作戦なのです。ほら、かっちょよくて使いやすいエディタとかあれば、動作データもさくさくできるかもしれないでしょ〜。 う〜む、画像が表示されない… というわけで、とりあえずフルパスで記述していた画像ファイルのパスを相対(というかディレクトリ情報を抜いた)パスに変えました。左の画像は、WideStudioのアプリケーションビルダでプロパティを表示したところです。これで、とりあえず、実行ファイルと画像ファイルを同じフォルダに置いておけばいつも表示されるようになりました。 これ、実行ファイルに入れてしまう方法って無いんでしょうか?また調べてみようとは思いますが、これはこれで、ビルド無しで画像が入れ替えれていいような気がします。でも入れたいな〜。どなたかご存知じゃないでしょうか??? く、クラスってどうやって追加するの? ま、まさか、これがおまじないか… SACdefFileというクラスを定義しようとしていたんですが、これのソースファイルをSACdefFile.h、SACdefFile.cppとしていました。そしたら上記のエラーに引っかかっていたんですが、これを、SSACdefFile.hとSSACdefFile.cppにしたら通ってしまいました。ソースファイル名の頭に「S」を追加して、名前を変えてみたわけです。不思議です。でも、SACdefFileSrc.h、SACdefFileSrc.cppとやってもダメなんですよね〜。お作法かなぁ。 ちなみに、自分で独自に作成したソースコードをコンパイルの対象に入れるには、「プロジェクト」−「プロジェクトの設定」にて「コンパイル」タブを開いて、「追加オブジェクト」にオブジェクトファイル名を追加すればいいです。先の、SSACdefFileの例で行くと、SSACdefFile.oと書いてやればOKです(「SSACdefFile.cpp」では無いのでご注意)。 ファイルの内容をリスト表示 んでまあ、とりあえず、ファイルを読み込んでWSClistDataクラスにWSCstringをがばがばとnewしてくっつけて読み込んでやって、それを試しにWSClistで表示してみたら、左上のようになってしまいました。なんか変でしょ?表示がかけています。これは悩みました。なぜだろう?なぜだろう? 実は、ファイルから読み込んだ時に、「改行コード」が入ったままになっていて、それをWSClistにそのままaddItem()していました。もし、同じような表示になった方がいましたら、「改行コードを削除」してやればOKですよ。んで、左下になりました。 ちなみに、改行コードを削除するには、WSCstringクラスに便利な関数がありまして、delLineFeed()で一発で外れます。なかなか便利です。 setPropertyはすごい! void STM_opeSlideServoDeg( WSCbase* object ) { int nIdx, nDeg; nDeg = object->getProperty( WSNvalue ); nIdx = object->getProperty(WSNuserValue); STM_aplblServoDeg[nIdx]->setProperty( WSNlabelString, nDeg ); }
| ||||
2004/03/24 |
スライダーネタで、おかださん(OKADA Official Site)から、メールを頂きました。おかださんのモーションデータ作成ツールって、な、なんとExcel+VBなのね…。現物見て、びっくりしました。詳細は、おかださんのHPを参照してください。見ると、そうかExcelさえあれば、フリーツールと組み合わせて、いい感じのものができてしまうではないか〜というのがわかってしまいました。 実は、以前、ホームページの方は拝見させて頂いていたのですが、「VBで」というところだけ覚えていまして、Excelの方は忘れていました。「ロボット製作のページ」−「R2N-series製作日記」の下のほうにあります。ExcelからVBでシリアル通信ライブラリを呼び出して、User Formで作った操作画面です。よく考えると、これも結構、アリだなぁって思ってしまいました。ほら、Excelって、表計算ソフト。動作データって、ほとんど表だったり、計算いっぱいだったりするわけですし、初期データなどもセルに書いておいて、コアにシリアルでアクセス。実は、なかなか良いんではないかと、思うわけです。 ここから第2のポイントで、今日のお題なんですが、各スライドバーとその受け関数を、割と単調にコーディングされていまして、これについて、「簡単ではまった」(邪道と思いつつ始めたら、意外に簡単であったという意味だと思います)とのコメントを頂きました。そこで、SISOは考えました。 わらひは、いきなり複雑なことをやろうとしている気がする… といわけで、WideSudioでも、同じようなことができるというのをおかださんにアピールしつつ、こっそりExcel路線もおもしろいと思いつつ、単純なスライドバーの生成をやります(最初からそうしなさいって感じですよね〜)。ひょっとしたら、正式採用かな?ま、今は、小手試し期間です(^^; 単純にサーボ制御用スライドバーを作るには? トグル:tglServoDegCtl00、tglServoDegCtl01 前回、ボタンではなく、ラベルを使用していたのですが、今は、気分でボタンにしています。「押すと原点復帰」とかしたらおもしろいかな?と思いまして。また、ボタンだと、ラベルと違って表示にグラデーションが使えるので、デザイン的な理由もあったりします(笑)。 後は、スライダにVALUE-CHのイベントプロシージャをつけます。1つめは、SDCmovSlider00、2つめはSDCmovSlider01とします。そうすると、ソースコードが生成されます。SDCmovSlider00を例に… まずは#includeの次に、
を追加します。次に、関数の中身として、次の1行を追加します。
SDCmovSlider01の方も同様にしてください(ただし00は01にしてくださいね)。これで、スライダを動かすと、ボタン上の数値がぐりぐり変わるソフトができます。サーボの個数分だけ、これを繰り返して作ればOKです。一見大変そうですが、やってみると、それほどでもないです。う〜む。意外でした。あれこれ考えるよりは楽かも。しかも、WideStudioは、プロパティで「ユーザー設定値」というのが設定できるので、これを駆使すればさらに楽ができるかも…。んで、できあがりはこんな感じです。 ところで、以前、スプラッシュウィンドウの時に紹介した、ウィンドウにグラフィックファイルを貼り付ける機能の話、覚えていますか?あれとこれを組み合わせると、お楽しみの…これができます。う〜ん、なかなかきれいにできました。
| ||||
2004/03/30 |
本日は、最近発見した、ちょっとしたWideStudioの小技を紹介します。 へ、編集しちゃってもいいのかな? WideStudioでごちょごちょと、新SIPHA TERM画面を作っていますが、部品を作っているうちに、Inspector(アプリケーションビルダの左側に表示されてるオブジェクトのツリーウィンドウ)に並んでいるオブジェクトの順番が気に入らなくなることがありませんか? どうも、作っている順番に表示されていくようでして、「あ、あのボタン忘れた」とか言って追加すると、下のほうに来てしまいます。実は、プロポをエミュレーションする画面を作っていたんですが、画面上のボタンの順番に並んでいないと、どうもやりにくい!というわけで、ちょちょっとWideStudioの定義ファイルをのぞいてみました。 ふむふむ。「ウィンドウ名.win」(たぶん、メインウィンドウと呼ばれる単位だと思います)というファイルにオブジェクト情報があるようですね。テキストファイルなので、エディタで「えい」と開けば内容を確認することができます。よくみると、この中に定義してある順番で表示されているようです。「#OBJ」で始まっている行が1オブジェクトの定義順のようです。 「むむむ、ひょっとしてこれの順番を入れ替えれば…」、たぶん正規技じゃないと思いますので、ファイルをコピってバックアップしておいてください。また、WideStudioは終了させておいてください。 WideStudioの動きを良く見ていると、このファイルをアプリケーションビルダでまず作り、ビルド時に、「ウィンドウ名.cpp」と「ウィンドウ名.h」いうファイルを自動生成し、この中にオブジェクト生成のソースコードが生成されるようですね。おまけ情報としては、これらのファイルをいくら編集しても、ビルドのたびに戻ってしまうのでダメ、ということになります。そっとしておいてあげましょう。 というわけで、「ウィンドウ名.win」の中身をエディタでちょいちょいと入れ替えてWideStudioを再起動…お、変わりました。これで、気にせずオブジェクトをぐいぐい追加できます(^^)。別に結果には何も影響を与えないのですが、気分気分!これで気分上々です。 というわけで、小技でした。 WideStudio、オブジェクトがごちゃごちゃする時はFormに貼り付けちゃえ 左の画面は、「プロポエミュレータ」を作ろうと思って作った画面なんですが、左右の9個組みボタンは、1つのFormオブジェクト上に配置してあります。こうすると、Inspectorには9個ずつ階層化して表示されるようになります。これだけでも結構気分がいいのですが、さらに!1つ作って、コピーすれば、もう1組の9個ボタンウィンドウを作れることが発覚。ぶらぼ〜! そ、そして、まだ利点があります。全体の表示座標を変える時に「おお、Formに貼り付けておいてよかった〜」というのをさらに実感しました。う〜ん、楽チン。つ〜のも、それぞれのボタンの大きさはあまり変えないのですが、全体のレイアウトを見直すときに、表示座標を変えたいときがあります。実際にあったのは、大元のウィンドウサイズを変えたときです。「うぅ、でかかった」なんて時ウィンドウを小さくすると、全体の部品配置もバランスよく見直したりするわけですが、こんな時、Form上に配置してあると、Formの座標をずらすだけで、ボタンが9個組で移動してくれます。というのも、Form上に配置する場合、それぞれのボタン表示座標は、Formの左上が(0,0)の原点になります(各ボタンがFormの子供になるわけですね)。そんなわけで、Formさえ移動すればいいのです。 というわけで、いいか悪いか良くわからないですが、オススメ!のやり方です。
| ||||
2004/06/01 |
WideStudioのWSCindexForm 「う〜ん、こまこましたウィンドウが増えてやだなぁ〜。」設定系のウィンドウを作っていると、こんなぼやきが出る時があります。そこで、てぃろりろりん♪「いんでっくすふぉぉむぅぅ」 「タブ画面」ってご存知です?実は、正式になんと呼ぶのかは知らないのですが、Windowsとかの設定画面によくある、上の方のインデックスみたいなところをクリックすると、同じウィンドウ上でいくつかの設定画面を切り替えられるアレです。これをWideStudioでやってみたのですが、すごく簡単! オブジェクトボックスから貼り付けたいウィンドウへ、「WSCindexForm」をドラッグ&ドロップします。 後は、ビルドすれば「あこがれのタブウィンドウ!」ができますよ。すごい簡単でブラボーです。さて、注意点です。「プロパティ」の「ユーザー設定値」(WSNuserValue)を見てください。よくみると、「INDEX01」に貼り付けた部品の設定値は「1」、「INDEX02」に貼り付けた部品の設定値は「2」になっています。これは、部品を貼り付けるときに、ビルダが自動的に割り振ったもので、どうやら、WSCindexFormは、この設定値によってどのインデックスにどの部品を割り付けるかを判定しているようです。 というわけで、WSCindexFormを使うと「ユーザー設定値」によってなんかする、というプログラムが書けなくなりますので、要注意です。できれば別にして欲しかったトコロではありますが、それにしても、う〜む、WideStudio、よくできてるな〜。
| ||||
2004/10/13 |
久しぶりの更新です。例によって出張していまして…。日本は涼しいです。ちょっと風邪気味。 さて、今日は超久しぶりのWideStudioネタです。 最近、SIPHA TERMの改良を始めました。久しぶりに触るので半分忘れかけていますが、開発時、急いで作っていたため、いろいろアップできなかった情報があることを思い出しました。そんなわけで、ぼちぼちと思い出しがてら、小技みたいなものをアップしていこうと思います。 WideStudioでTRACE表示 WideStudioには、WSGFtrace( WSCstring )という、グローバル宣言されている関数がありまして、これを呼び出すと、TRACEウィンドウに文字列を表示してくれます。 TRACEウィンドウの出し方ですが、プログラム実行時に「ビルド」−「トレース実行」とすることによりTRACEというウィンドウが開きます。自分でWSGFtrace()を埋め込まなくても、ウィンドウにはアプリケーションビルダで設定したイベントがずらずらと表示されるようになっています。そういうわけで、最初からTRACE表示をさせておくと見づらいので、ここぞ!という時に、「start」を押します。そうすると、イベントとともに、WSGFtrace()で設定した文字列が表示されます。 では、どうやって実装するかやってみます。 サンプルプログラムの作成とトレースウィンドウの表示 これに、マウス押下イベント処理を追加してみます。「プロシージャ」で、「プロシージャの追加」をします。 マウス押下イベントは、「MOUSE-PRESS」という起動トリガになります。名前は適当ですが、いつもこんな感じでつけています。MOUSE-PRESSだから「XMP」、もしACTIVATEだったら「XAC」なんてのを後ろにつけています。ちなみに「X」は「実行(Execution)」ということでつけています。 これで「作成」を押したら、そのまま「ビルドオール」してください。で、ここからがミソ。プログラムを実行するときに、「トレース実行」を選択します。 これです。これで実行すると、トレースウィンドウ付きでプログラムが実行されます。そして、実行すると、次のような状態になります。ちょっと見づらいですが、左下にあるのが今回作ったウィンドウで、後ろにでっかくでているのがトレースウィンドウです。「start」と「cancel」ボタン(なぜに小文字?)が右下にあるのがわかると思います。 それでは、さっそく、実感してみましょ。「start」を押してマウスで、プログラムで作ったウィンドウの方をクリックしてみると… お、何か表示されましたね!ちょっと上の画面では見づらいので、拡大したものを下に載せます。 はい、こんな感じで表示されています。なになに?WTSwin(今回作ったウィンドウ)が<マウス押下>イベントプロシージャ−を実行して、スタートしてエンドですか、ふむふむ。 このように、TRACEウィンドウでは、イベントプロシージャの実行状態などが表示されます。で、ここが本題ですが、このウィンドウにはプログラムからも表示をさせることができます。それが、先に書きました、WSGFtrace()です。 WSGFtrace()でTRACEウィンドウに表示
WSGFtrace()の引数は、WSCstringで宣言されていますが、このように文字列を渡しても大丈夫です。のあたりは、C++のOperator演算子がどうたらこうたらのような話だったと思いますので省略します(単に説明できるほど詳しくないだけ…)。では、さっそく「ビルドオール」して、「トレース実行」してみてください。「start」を押すのも忘れないで下さいね。 3行目に、無事、「トレース表示」と表示されています。こんな感じでTRACEウィンドウに文字列を表示します。例えば、内部処理でのちょっとした結果の表示などに使えます。また、WSGFtrace()は、TRACEウィンドウが無ければ、何も動作しないようになっていますので、不要になったからといって削除する必要は無く、そのまま埋め込んでおいても大丈夫です。 もっと便利にTRACE表示
とりあえずテストということで、先ほどのイベントプロシージャ実行関数のソースファイルに書き込んじゃってください。また、va_listとかがわからない方は、いわゆるCの標準関数ですので、がんばって調べてみてください。
じゃ、「ビルドオール」して「トレース実行」してみましょ。 おお、ちゃんと出ました。これでprintf()と同じイメージで使えます。便利ですので、お試しくださいな。また、もし、もっといいデバッグ方法を知っていらっしゃる方がいましたら、ぜひ教えてください。
| ||||
2005/01/09 |
WideStudio
v3.80-7 ちょっと前に、「Wide Studioで作ったアプリケーションって、どのDLLが必要なんだろう?」と思って少し調べていたんですが、これを使えば、WideStudioがインストールされていないWindowsにアプリを入れても動作できます。うちのLibretto L1は、Dual Bootにしてあって、何にも追加DLLが入ってない方のWindowsがあるので、そこで試してみたところ、バッチリ動作しました。 き、気づかなかった… これは、v3.80のリンクタブですが、リンク方式□「スタティックリンク(DLL無し)」と書いてありますこれにチェックを入れると、スタティックリンクのアプリケーションを作成することができます。じゃあ、V3.70の方はどうなっていたかといいますと 、 なんと、こういう表示になっています。この状態が「ダイナミックリンク設定」です。今思えば、試しに押してみてもよかったチェックボックスですが、ちと難しかったです…。でもチェックボックスって、「チェックするとその状態になる説明文が書いてある」のが多いと思うので、気が付きませんでした。ちなみに、ここの動き、なかなか凝ってまして、チェックすると… テキストが「スタティックリンク(DLL無し)」に変わります。 ダイナミックリンクライブラリについて 対して、スタティックリンクでアプリケーションを作成すると、アプリケーションのサイズは大きくなりますが、パソコン毎のライブラリインストール状態を気にしなくてよくなります。 気になる実行ファイルのサイズですが、SIPHA TERMで試してみたところ、380Byteのプログラムが3.6MByteになりました。実行ファイルのサイズが大きくなったとはいえ、実際に、小さいサイズのアプリを起動しても、恐らく同じだけWideStudioのDLL(ダイナミックリンクライブラリ)がロードされるわけなのでパフォーマンスに差は無いと思われます。ちなみにZIPで圧縮してみたら1.2MByteぐらいにはなりました。WideStudioでプログラムを作って人に配布する場合は、スタティックリンクにしておいた方が手堅そうですね。
| ||||
2005/01/11 |
リブレットL1は、画面サイズが1280x600 # 何気に勢いでやってしまいましたが、後で、どっちでもよかったかな?と思ったことはヒミツ。 背景画にあわせてウィンドウサイズを変更するには? さて、ざくっと要点解説ですが、TSC16もそうなんですが、画像データ、基本的にはウィンドウの背景画として読み込ませています。ウィンドウのプロパティで、「背景画」というのがありますが、これをプログラムで操作しています。TSC16の場合は直接ソースコードで指定していますが、この項目にsetProperty()すれば画像ファイルを動的に読み込むことができます(簡単〜♪)。 さて、WideStudio、ヘルプファイルを読むと、どうやら画像扱うためには「WSDimage」というクラスを通じて扱うようになっているようです。また、その画像元ネタは、「WSGIappImageSet」というプログラム内でグローバルに宣言されている(WideStudioでアプリケーションを作成すると、そのアプリケーションに自動的に引っ付いていると理解しておいてください)画像管理オブジェクト?から引っ張ってくるようです。 そんなわけで、まずはこんなコードで初期化されます。 WSDimage* pimgBasePic; // test.jpg のイメージインスタンスを取得。 pimgBasePic = WSGIappImageSet()->getImage( "test.jpg" ); これで、「イメージインスタンス」とやらが取得できますので、ここからサイズ情報を取り出し、自ウィンドウのウィンドウサイズを変更します。まずはサイズ取得です。サイズ取得用のメソッドが用意されていますので、以下のようなコードでさらっと読み出すことができます。 unsigned short usWidth, usHeight; usWidth = (unsigned short)pimgBasePic->getImageWidth(); // 画像横幅の取得 usHeight = (unsigned short)pimgBasePic->getImageHeight(); // 画像高さの取得 後は、この値を使って、自ウィンドウのプロパティを操作するだけです。 object->setProperty( WSNwidth, usWidth ); // ウィンドウサイズの設定 object->setProperty( WSNheight, usHeight ); // ウィンドウサイズの設定 object->setProperty( WSNbackPixmap, "test.jpg" ); // 背景画の設定 「object」というのは、自分自身のクラスポインタです…と書くとややこしいのですが、簡単に言うと、 WideStudioでイベントプロシージャを記述すると、自動的にこの「object」というポインタが渡されるコードが生成されるのですが、呼び出し元の情報(ポインタ)がセットされるようになっています。 そこで、呼び出し元を操作したい場合は、このポインタを使って操作します。「object」の型は「WSCbase」というクラスで、プロパティ操作等のメソッドを含んだクラスです。よって、プロパティ操作をする場合、このクラスポインタをそのまましようすればOKです。 このように、WideStudioの場合、ウィンドウに対する操作は、ほとんど「setProperty」を実行することで行うことができます。つまり、ビルダの「プロパティ」ウィンドウから手入力であれこれしていることを、そのままプログラムで「setProperty」と書いていくだけで、同じことをすることができます。 プログラムコードと操作が直感的につながりやすいので、WideStudioで「いいなぁ〜」と思っている点の1つです。ところで、このプログラム、なんとなく無駄に2回も画像ファイルにアクセスしている気がするので、本当は、もっと良いやり方がありそうな気がします。う〜ん。
| ||||
2005/01/20 |
今日からROBO-ONEエントリー開始ですね!うちの進捗は、メカは、まだ未完成ですが、部品加工はほとんど終わっているので、週末ぐらいには形ができるかな〜ぐらいです。最近まで、SIPHA TERMのソースコード復活をやっていたので、そのまま、SIPHA TERMを改良してたりします。最近、しばらくプログラム触っていないと、プログラムの作り方を忘れてしまうんで、一気に!という感じです。そんなわけで、その中から出てきたTOPICをおひとつ。 マウスボタンチェック これまた、結構簡単だったので、やり方を紹介します。 WideStudioでは、「最後に押したマウスボタンを取り出す」機能があります。これを普通にボタンが押された時に呼び出される処理に追加してやればOKです。 具体的には、WSDmouseというクラスを使用します。 まずは、マウスのグローバルインスタンスを取得します。「???」な感じですが、SISOもよくわかってないです。きっと、アプリケーション中に、マウスを管理しているインスタンスとやらがあり、そこにアクセスするためには、まずは取得するということだと思って使っています。 WSDmouse* mouse = WSGIappMouse(); はい。これでマウスのグローバルインスタンスが取得できます。そして、後は判定するだけです。状態の取得は、getTargetBtn()を使用しますが、この返り値は次のように定義されています。 WS_MOUSE_BTN1 左ボタン WS_MOUSE_BTN2 中ボタン(ホイール) WS_MOUSE_BTN3 右ボタン 後はこれをSWITCH文などで振るようにコーディングするだけですね!ボタンが押された時の結果を表示するラベルを、"vlabClickStatus"という名前で作ってそこのところをコーディングすると、次のような感じになります。 WSDmouse* mouse = WSGIappMouse(); switch( mouse->getTargetBtn()){ case WS_MOUSE_BTN1: // 左ボタン vlabClickStatus->setProperty( WSNlabelString, "左ボタン" ); break; case WS_MOUSE_BTN2: // 中ボタン vlabClickStatus->setProperty( WSNlabelString, "中ボタン" ); break; case WS_MOUSE_BTN3: // 右ボタン vlabClickStatus->setProperty( WSNlabelString, "右ボタン" ); break; } 最後に、ヘッダファイルのインクルードと、ラベル部品の外部宣言も忘れずにしておきます。これでばっちりです。 「これでいいのかな〜」なんてちょっと思ったりしますが、今のところ、大丈夫そうなので、きっと大丈夫でしょう。もし間違ってたら連絡お願いいたします。
|
SISO-LAB Knowledge