人に聞けない痔の悩み、これでスッキリ >>

初めて投稿します。
現在BCBを使用してますがタイマー機能を使用して(使用無しでも^^)
作りたい機能があるんですけど、どうしたらいいのか息詰まってしまって誰か教えて下さい。

とりあえずフォームにボタンを用意してボタンを押したら
時間が流れまたボタンを押したら5秒止まって勝手に動きだす
プログラムを作りたいんです。色々本やネットを検索したんですけど
駄目でした。誰かご教授下さい。
ちなみに最初の時間が流れるのは時計でも何でも動いてるのが
分かればどんなものでも大丈夫です。文字が横に流れるとかでもとりあえず動いていて止まってまた動きだす感じです。

ボタンを押したら時間が流れて0秒になったら最後ShowMessageが
出るプログラムは出来たのですが。上記のがなかなか出来ません。
どうぞ宜しくお願いします(ノ_-、)

A 回答 (3件)

サンプルです。


bool bFirst;
を、privateに追加して、フォームにタイマーとボタンを配置して、
以下ですね。
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
bFirst = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(bFirst){
bFirst = false;
Timer1->Enabled = true;
}else{
Timer1->Enabled = false;
bFirst = true;
Timer1->Interval=5000;
Timer1->Enabled = true;
Button1->Caption = "5秒休憩中だよ。";
Button1->Enabled = false;//
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Timer1->Enabled = false;
if(!bFirst){
Button1->Enabled = true;
SYSTEMTIME st;
::GetLocalTime(&st);
AnsiString As;
As.printf("%d:%02d:%02d-%03d",st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);
L->Caption = As;
Timer1->Enabled = true;
Button1->Caption = "押したら5秒とまるよ。";
P1->Enabled = true;
}else{
Timer1->Interval=10;
bFirst = false;
Timer1->Enabled = true;
}
}
//---------------------------------------------------------------------------
    • good
    • 0
この回答へのお礼

ありがとうございました!参考になりました!!
感謝です。

お礼日時:2007/11/09 00:15

これは言語の問題というよりは、ロジックを組み立てる問題です。



初期起動かどうかのフラグをリセットする

タイマーはとまっている

ボタンが押されたら0.1秒単位でタイマーを起動する
と同時に、初期フラグを立てる

タイマーのイベントで初期フラグがたっていたら時計を表示

ボタンが押されたらタイマーを一旦とめ、
初期起動かどうかのフラグをリセットし、
5秒単位でタイマーを起動する

タイマーのイベントで初期フラグがたっていなかったら
一度タイマーをとめ、初期フラグを設定して、0.1秒単位で
タイマーを起動する

元に戻る

こんな形であれば、ボタンもタイマもひとつですみます。
    • good
    • 0
この回答へのお礼

なるほど!タイマ機能は二つ必要なのかと思ってましたが
色々と応用があるのですね!ありがとうございました。

お礼日時:2007/11/09 00:16

とりあえずサンプル。


わからない点はヘルプをしっかり読む。
それでも判らなければ判らない点を具体的かつ明確に再質問してください。

フォーム上にTTimerを2つ、TLabelを1つ、TButtonを2つぽとりぺたりする。
それぞれTimer1、Timer2、Label1、Button1、Button2とする。
以下の通り設定
 Timer1:メインの作業をするタイマー。Intervalを1000ms、Enableをfalseに設定。
 Timer2:Timer1を5秒停止させるためのタイマー。Intervalを5000ms、Enabledをflaseに設定。


Button1のOnClickイベントで
 Timer1->Enabled = true;

Button2のOnClickイベントで
 Timer1->Enabled = false;
 Timer2->Enabled = true;

Timer1のOnTimerイベントで
 Lavel1->Caption = Time();//メインの作業。とりあえず現在時刻を表示。

Timer2のOnTimerイベントで
 Timer1->Enabled = true;
 Timer2->Enabled = false;
    • good
    • 0
この回答へのお礼

分かりやすく教えて頂いてありがとうございました。
お陰さまで上手くいきました^^

お礼日時:2007/11/09 00:18

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC++ Builderで文字列をバイトにする方法

C++ Builderでプログラミングをやっているのですが、

String memo1 = "あいうえお";


という文字列を

unsigned char test_bin[1000];

バイトで宣言した配列に



test_bin[0] = memo1の1バイト目;
test_bin[0] = memo1の2バイト目;
test_bin[0] = memo1の3バイト目;
test_bin[0] = memo1の4バイト目;
test_bin[0] = memo1の5バイト目;


このように、文字列データのバイト数値を数値変数に代入させることはできますでしょうか?


どうぞ、ご教授の程よろしくお願い致します。

Aベストアンサー

No1です
>このようにコピーした時には文字コードは考慮されないのでしょうか?
何か勘違いされてるような気がしますが文字コードはコピー元の文字で考慮すべき問題です
少なくても strcpy 関数にて文字コードが変化することはありません

元々格納されていた文字列がユニコードなのであればユニコードの文字コードがコピーされ
SJISであればSJISの文字コードがそのままコピーされます

QBorland C++Builder 6で初心者に参考になるサイトを教えてください。

Borland C++Builder 6で初心者に参考になるプログラムの書き方が解るサイトを教えてください

Aベストアンサー

リンク集ですが、張っておきます。
http://www.yukibow.com/data/prog/index.html

関数リファレンスはすぐに表示できるようにしておくといいでしょう。

Q[Delphi] Socketのエラーを抑制する方法

バックグラウンドで動作して、インターネットからWebの新着情報を持ってきて画面の隅に表示するというアプリケーションをDelphi + TClientSocketで作成しています。

フォーム作成時 : ClientSocket1.open;
接続時 : ClientSocket1.socket.sendtext(リクエスト内容);
受信時 : フォームの情報を更新
タイマー : 一定時間おきに接続イベントを発生

そこで質問なのですが、ネットに繋がっていない等でDNS参照に失敗すると

「Windowsソケットエラー API ASync Lookup」

と、APIからエラーが返ってきます。一定時間おきにチェックするので、非接続時にこれが毎回出てくるとうざいということで、接続失敗しても黙っているように変更したいのですが、どのようにしたら良いのでしょうか・・・。

TClientSocketのヘルプが無くてわかりませんでした(汗

Aベストアンサー

ClientSocketのイベント「OnError」にて、「ErrorCode:=0;」を設定してください。

以前私も苦労したことがあります。

QC++Builderで別Formから呼び出したFormを終了させるには

C++Builderで別Formから呼び出したFormを終了させるには
わかりにくくてすいませんが

Form1から Form2を呼び出し
そのForm2からForm1を終了させたいのですが
もちろんForm2も終了されてもかまいません
又はアプリケーションごと
すべて終了させてもかまいません

よろしくお願いいたします

Aベストアンサー

>Form1から Show()でForm2を立ち上げて
>そのForm2からClose()で
>Form1ごと閉じたかったのですが閉じれなかったので
>もちろん
>Form1 = new TForm1(this);
>Form1->Close();
>はしたのですが やり方がおかしかったのでしょうか?

 インスタンスとクラスの関係を理解しましょう。
Form2のインスタンス中でそんなことやったら、Form1の今表示されているウインドウ(に関連するメモリ)は宙に浮き、新しいウインドウが作られ、それを閉じる、というようなことをやっています。

 Form2にForm1を参照させて、Form1->Close();だけで閉じませんでした?
#「終了」は、Closeで良かったかいな??

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Qエディットボックスの入力制限について

いつもお世話になっております。
VS2005でC++を使ってWindowsプログラミングの作成を行っています。

エディットボックスに半角数字のみ入力するような制限はできますが、
この制限をもっと詳しくし、例えば数字の0~60までしか入力できないようにすることは可能でしょうか。

ご教授お願いいたします。

Aベストアンサー

Win32 APIを使っていて、入力があるたびに値のチェックをするのであれば、WM_COMMANDの処理で通知コードがEN_UPDATEまたはEN_CHANGEの場合を扱えば実現できます。
たとえば、エディットボックスのあるダイアログボックスのメッセージハンドラをに以下のような文を挿入すれば、エディットボックスの入力値が変わるごとに入力チェックをしてくれます(半角スペース*2を全角スペースに変換しています)。

case WM_COMMAND:
(挿入ここから)
 if (HIWORD(wParam) == EN_UPDATE/* 表示の変更前にチェックするならEN_CHANGE */ && LOWORD(wParam) == IDC_EDIT/* チェックを行うエディットボックスのコントロールID */)
 {
  char buf[256]; /* 文字列処理用バッファ */
  int value; /* 入力値 */

  GetWindowText((HWND)lParam, buf, 255); /* エディットボックスの文字列取得 */
  value = atoi(buf);
  if (value < 0 || 60 < value) /* 入力値チェック */
  {
   /* 入力値が範囲外であることをユーザーに通知する */
   MessageBox(hDlg, "0から60までの間の数を入力してください。", "入力エラー", MB_OK);
  }
 }
(以下、他のWM_COMMANDメッセージ処理)

ただし、入力値チェックを1からにして動かしてみればわかりますが、入力があるたび値のチェックをすると使う側からすればウザいです。

このような場合、自分ならば、値を入力ではなく選択させる(コンボボックスやスピンコントロールなどを使って)か、入力チェックを入力した値を利用/取得する時点で行うようにします。

Win32 APIを使っていて、入力があるたびに値のチェックをするのであれば、WM_COMMANDの処理で通知コードがEN_UPDATEまたはEN_CHANGEの場合を扱えば実現できます。
たとえば、エディットボックスのあるダイアログボックスのメッセージハンドラをに以下のような文を挿入すれば、エディットボックスの入力値が変わるごとに入力チェックをしてくれます(半角スペース*2を全角スペースに変換しています)。

case WM_COMMAND:
(挿入ここから)
 if (HIWORD(wParam) == EN_UPDATE/* 表示の変更前にチェックするな...続きを読む

Qスレッドの安全な終了のさせ方

スレッドの安全な終了のさせ方

 メインスレッドにてCreateThread命令を使い、あるサブスレッドを作りました。
このサブスレッドは内部でmallocを使い動的に配列領域を確保して
その配列領域をforループ等で「かなり時間の掛かる処理」として繰り返し
アクセスしています。
ループが終了した時に「free」を実行してmalloc領域を開放しています。

アプリ終了時にメインスレッドからこのサブスレッドを終了させるのに
メインウインドウにWM_DESTROYメッセージが送られた時、これまで単に
そこで「CloseHandle(hSubThread);」とだけ書いていたのですが、
もしかしたらこれでは場合によっては(サブスレッドがループ処理中だったら)
malloc領域が開放されずにリークしてしまうのではないかと思いました。

 そこでイベントオブジェクトを使い、サブスレッドがループ処理中の
時には非シグナル状態にして、ループが終了しfreeで領域を開放した後
シグナル状態にするということにして、メインスレッドはそれを
WaitForSingleObjectで待つという構造にしました。

ところが「メインスレッドに待ちを作るな」という言葉通り、これでは
上手く行きませんでした。サブスレッドはその時間の掛かる処理の
最中でSendMassage等でメインスレッドの処理を促すような命令を
(例えばその処理の進捗状況を表示するなど)を幾つも行っていたので、
もしWaitFor~でメインを待たせると「サブスレッドの処理も進まなくなり
結果両方がロックして動かなくなってしまう」という悲しい状況に
嵌ってしまうのです。

SendMessageを徹底的に無くすということも考えたのですが、
(例えばPostMessageに書き換えるなどもやってみたのですが、これは
全く意図した動作をしてくれない場合もあり)、別の方法では
どうしても代替できないケースもあって、全て消すというのは
現実的ではないのかもと。。

 このようなサブスレッドを安全に終了させるにはどうしたら良いでしょうか?
あるいは単にデストロイ時にCloseHandleとするだけでも良いのでしょうか?

スレッドの安全な終了のさせ方

 メインスレッドにてCreateThread命令を使い、あるサブスレッドを作りました。
このサブスレッドは内部でmallocを使い動的に配列領域を確保して
その配列領域をforループ等で「かなり時間の掛かる処理」として繰り返し
アクセスしています。
ループが終了した時に「free」を実行してmalloc領域を開放しています。

アプリ終了時にメインスレッドからこのサブスレッドを終了させるのに
メインウインドウにWM_DESTROYメッセージが送られた時、これまで単に
そこで「CloseHandle(hSu...続きを読む

Aベストアンサー

>SetEvent(hEventObject1);//イベントオブジェクトをシグナルに
スレッド終了を判断する場合はスレッドのハンドル自身を見た方が確実です。
HANDLE thread_handle = ::CreateThread(略);
(略)
::WaitForSingleObject( thread_handle , INFINITE );
スレッドは終了時にハンドルがシグナル状態になります。


>SendMessage(hMainWnd,....);
>//メインウインドウに何かのメッセージを送信
>//なってた時に処理が進まなくなる。
名前から察するにhMainWndはメインスレッドで動いているようですが
そのメインスレッドの処理がWaitForSingleObjectによって止まっているのなら処理は返ってきません。
つまりサブスレッドがメインスレッドとなんらかのやりとりをしたいなら、
この時点でメイン側はWaitForSingleObjectで待ってはいけません。

1. Main -> Subに終了前準備しろと通知
2. Sub -> Mainに終了前準備完了を通知
3. Main -> Subに終了しろと通知
4. MainはSubが終了するのをWaitForSingleObjectで待つ。

>SetEvent(hEventObject1);//イベントオブジェクトをシグナルに
スレッド終了を判断する場合はスレッドのハンドル自身を見た方が確実です。
HANDLE thread_handle = ::CreateThread(略);
(略)
::WaitForSingleObject( thread_handle , INFINITE );
スレッドは終了時にハンドルがシグナル状態になります。


>SendMessage(hMainWnd,....);
>//メインウインドウに何かのメッセージを送信
>//なってた時に処理が進まなくなる。
名前から察するにhMainWndはメインスレッドで動いているようですが
そのメインスレッドの...続きを読む

QC++ Builder6 をふたたび動かしたい

数年前まで C++ Builder6を使ってコマンドラインプログラムを作っていました。
久しぶりに使おうとすると、以下のエラーメッセージがでて新規プログラムが作れません。再インストールをしても同じです。
C++ 5.5 がフリーで出ているようなんですが、元のプログラムが複数あって、Builderの環境で使いたいと思うのです。
すでにボーランド社はありません。
どのようにすれば解決できるのかわかれば教えてください。よろしくお願いします。

C:\Program Files\Borland\CBuilder6\bin\bcb.$$$ から C:\Program Files\Borland\CBuilder6\bin\bcb.droに変更できません。

Aベストアンサー

お使いのOS環境等が書かれていませんが、おそらくWindows 7 か Vista ですね。
Vista以降は UAC により C:\Program Files 以下への書き込みが出来なくなっていますので、
UAC をオフにするか、
C++ Builder を C:\Program Files 以外のフォルダにインストールしてみてください。

http://blog.livedoor.jp/sayama_it/archives/50925382.html

なお、C++ Builder は、今はエンバカデロ社が引き継いでいます。C++ Builder 6のインストールにはレジストレーション処理が必要ですが、今もC++Builder6の使用許諾登録処理も行っています。
http://www.embarcadero.com/jp/support

Q”wchar_t*型は渡せない”というエラー

現在、ifjpeg.spiのDLLファイルで画像データを表示させるプログラムを作成中です。
このプログラムで、

if( IsSupported(OpenDialog->FileName.c_str(),theFile) != 0 )


このプログラムでビルドを行うと次のようなエラーが出ます。

[BCC32 エラー] Unit1.cpp(106): E2034 'wchar_t *' 型は 'char *' 型に変換できない
[BCC32 エラー] Unit1.cpp(106): E2340 1 番目のパラメータは char * 型として定義されているので wchar_t * 型は渡せない


”IsSupported”は

ProcIsSupported IsSupported =
(ProcIsSupported)GetProcAddress(hSPI, "IsSupported");

このように宣言していて、


typedef int __stdcall (*ProcIsSupported)(LPSTR,DWORD);


このようなプログラムなのですが、解決方法を教えて頂けませんでしょうか?

現在、ifjpeg.spiのDLLファイルで画像データを表示させるプログラムを作成中です。
このプログラムで、

if( IsSupported(OpenDialog->FileName.c_str(),theFile) != 0 )


このプログラムでビルドを行うと次のようなエラーが出ます。

[BCC32 エラー] Unit1.cpp(106): E2034 'wchar_t *' 型は 'char *' 型に変換できない
[BCC32 エラー] Unit1.cpp(106): E2340 1 番目のパラメータは char * 型として定義されているので wchar_t * 型は渡せない


”IsSupported”は

ProcIsSupported IsSupported =
(ProcIsSupport...続きを読む

Aベストアンサー

質問するには、もう少し情報があった方がいいでしょう。
既にある回答の情報から、C++ Builder のようですが、2009 or 2007 以降、ダイアログにある文字データの型が AnsiString から、UnicodeString に替わりました。
このため、c_str() をとっても、char * ではなく、wchar_t* が帰ってきます。

で、横着をするのなら、UnicodeString が AnsiString にキャスト可能であることを使って、

if( IsSupported(OpenDialog->FileName.c_str(),theFile) != 0 )

を、

if( IsSupported(static_cast<AnsiString>(OpenDialog->FileName).c_str(),theFile) != 0 )

と、一度 AnsiString にしてから、.c_str() をとると、char * が帰ってきます。

QButtonの色

Borland C++ Builder6を使っています。
かなり素朴な質問なのですが,Formに配置したButtonの
色はどのようにしたら変えられるのでしょうか??
知っている方がいましたら教えて下さい.
お願いしますm(__)m

Aベストアンサー

確かWindowsの仕様でButtonの背景色は変更できなかったと思います。
もし、実現するとすれば、TBitBtnを使ってBiBtnにイメージを取り込むあるいは以下URLで紹介されているコンポーネントを使用することになります。

http://www.kobira.co.jp/sakura/

以上、参考になれば幸いです。


人気Q&Aランキング