C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

全過去ログを検索

<< 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 >>
■56168  本スレッドが稼働しているときの別スレッドでのボタン操作
□投稿者/ anny -(2011/01/02(Sun) 20:33:40)

    分類:[C#] 

    開発環境
    Windows7 
    VisualC# 2008

    こんにちは,初めて利用させていただきますC#初心者です.
    別スレッドを立てても効果的な使い方ができず困っています.以下,実現したいことと現状です.

    したいこと
    Orig_studentというフォームが表示(Orig_student_Activatedメソッド)されたらhistory_reader_s(マウスで描画した軌跡を表すデータ)から1行ずつ読み取り,
    processPacket()というメソッドを使ってOrig_studentフォーム内のピクチャボックスに描画を行う(history_reader_sの内容を再現する描画を行いたい).
    stopButtonを押したら描画を停止し,viewButtonを押したら描画を再開したい.

    現状
    描画とボタン操作は同じスレッド内では無理だと考え,ボタン操作を違うスレッドを立てて行おうと思いましたが,実際は
    ・processPacket()を用いてピクチャボックスに描画することは可能ですが,stopButtonやviewButtonを用いて描画の停止・再生を行うことができない(描画中に停止・再生ボタンが使用できない).
    ・描画がすべて終わってから停止・再生ボタンを押すことが可能になる.
    となり,スレッドを立てている意味がありません.

    別スレッドでボタンとそのイベントハンドラを作成していますが,そのボタンを張り付ける先がOrig_studentフォームだからだめな気がします.
    描画中にボタン操作を可能にするにはどうすればいいでしょうか?

    描画部分(processPacket())はかなり面倒なことになっているので,ボタン操作のほうを別スレッドで行いたいです.

    以下ソースです.
    よろしくお願いします.

    public partial class Orig_student :Form
    {
    private void Orig_student_Activated(object sender, EventArgs e)
    {
    if (type == 1) return;
    if (hist_flag == false) return;
      
      history_reader_s = new StreamReader(CurrentDir+"\\"+histData_s[0].file); //読み込みたいファイルのStreamReader作成

    this.newTab_s = new System.Windows.Forms.TabPage();
    this.newTab_s.Size = tabPage01.Size;
    this.tabControl1.TabPages.Add(newTab_s);

    this.newPanel_s = new System.Windows.Forms.Panel(); //再生・停止ボタンを張り付けたいパネルを作成
    this.newPanel_s.Location = panel1.Location;
    this.newPanel_s.Size = panel1.Size;
    this.newPanel_s.BackColor = Color.White;
    this.newTab_s.Controls.Add(newPanel_s);

    Packet pk = new Packet();

    HistThread = new Thread(new ThreadStart(MakeButton)); //停止・再生ボタンを利用するスレッド作成
    HistThread.IsBackground = true;
    HistThread.Start();
    while (history_reader_s.Peek() > -1)
    {
    if (stop_flag == false)
    {
    pk.processPacket(history_reader_s.ReadLine()); //描画
    }
    }
    hist_flag = false;
    }
    private void MakeButton() //停止・再生ボタンを作成する
    {
    this.stopButton = new System.Windows.Forms.Button();
    this.stopButton.Location = button11.Location;
    this.stopButton.Text = "stop!!!";
    this.stopButton.Size = button11.Size;

    this.stopButton.Click += new EventHandler(stopButton_Click);

    this.viewButton = new System.Windows.Forms.Button();
    this.viewButton.Location = button10.Location;
    this.viewButton.Text = "view";
    this.viewButton.Size = button10.Size;


    this.viewButton.Click += new EventHandler(viewButton_Click);

    setButton SB = new setButton(Set); //フォームにボタンを張り付ける
    this.Invoke(SB);

    }

    private void Set()
    {
    this.newPanel_s.Controls.Add(stopButton);
    this.newPanel_s.Controls.Add(viewButton);
    stopButton.BringToFront();
    viewButton.BringToFront();
    }

    private void stopButton_Click(object sender, EventArgs e)
    {
    stop_flag = true;
    }

    private void viewButton_Click(object sender, EventArgs e)
    {
    stop_flag = false;
    }

    }

親記事 /過去ログ94より / 関連記事表示
削除チェック/

■56170  Re[1]: 本スレッドが稼働しているときの別スレッドでのボタン操作
□投稿者/ Azulean -(2011/01/02(Sun) 22:26:33)
    2011/01/02(Sun) 22:28:13 編集(投稿者)

    具体的なことが書かれてあるのは良いことではあるのですが読むのが大変だったりします。
    ここから私が書く前提として、きちんとすべてを読んでないことを先に断っておきます。

    No56168 (anny さん) に返信
    > 別スレッドでボタンとそのイベントハンドラを作成していますが,そのボタンを張り付ける先がOrig_studentフォームだからだめな気がします.
    > 描画中にボタン操作を可能にするにはどうすればいいでしょうか?

    基本的にできません。
    通常、この手のスレッドでループするような処理が必要なのであれば、その処理をワーカースレッドとするか、受信などのイベント受けて処理するイベント駆動にするべきです。


    > 描画部分(processPacket())はかなり面倒なことになっているので,ボタン操作のほうを別スレッドで行いたいです.

    この前提を崩せないのであれば、基本的にボタン操作を認めることはできない(=アプリがフリーズする)と考えるべきです。
    どうしても、どうしても何ともならないのであれば、Application.DoEvents を入れれば少しマシに見えるかもしれませんが、押せてはいけないボタンが押せる、もう一度イベントが発生するなどの弊害発生する可能性があります。

    原則として、Application.DoEvents の使用は控えるべきです。
    ただ、それに対する processPacket の改修・設計見直しに伴うリスク、今後の保守のリスク、Application.DoEvents を用いることによるリスクの発生確率・影響度が見えていません。これらのリスクを考慮した上で、どうするかご検討ください。


    # そもそも、ボタンを動的に作る必要はないのでは?Visible プロパティとか Enabled プロパティとかで何とかなりそうですし。
記事No.56168 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56172  Re[2]: 本スレッドが稼働しているときの別スレッドでのボタン操作
□投稿者/ anny -(2011/01/02(Sun) 23:05:42)
    Azulean様,読みにくいにもかかわらず回答を頂きありがとうございます.

    >>別スレッドでボタンとそのイベントハンドラを作成していますが,そのボタンを張り付ける先がOrig_studentフォームだからだめな気がします.
    >>描画中にボタン操作を可能にするにはどうすればいいでしょうか?
    >
    > 基本的にできません。
    > 通常、この手のスレッドでループするような処理が必要なのであれば、その処理をワーカースレッドとするか、受信などのイベント受けて処理するイベント駆動にするべきです。

    描画部分をワーカースレッドとしていないのには面倒な部分があるという点もありますが,描画するピクチャボックスもフォーム内(メインスレッド)のものなので,別スレッドを立ててもInvoke等で結局メインスレッドにアクセスする必要があり,あまり意味がない気がしました.
    そんなことはないのでしょうか?
    イベント駆動については勉強不足でよくわからないので少し調べてみます.

    > どうしても、どうしても何ともならないのであれば、Application.DoEvents を入れれば少しマシに見えるかもしれませんが、押せてはいけないボタンが押せる、もう一度イベントが発生するなどの弊害発生する可能性があります。

    Application.DoEventsというものがあるのですね.初めて知りました.
    とりあえず入れてみたところ,何とか思い通りには動くようになりました.
    私のプログラムだと現状では問題ないように思えるので,このまましばらく観察したいと思います.

    > # そもそも、ボタンを動的に作る必要はないのでは?Visible プロパティとか Enabled プロパティとかで何とかなりそうですし。
    別スレッドで作成すれば何とかなるのではないかと考えた悪あがきのためでした.
    ご指摘の通り動的に作成する必要はないようです.
記事No.56168 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56173  Re[3]: 本スレッドが稼働しているときの別スレッドでのボタン操作
□投稿者/ Azulean -(2011/01/03(Mon) 00:01:20)
    No56172 (anny さん) に返信
    > 描画部分をワーカースレッドとしていないのには面倒な部分があるという点もありますが,
    > 描画するピクチャボックスもフォーム内(メインスレッド)のものなので,別スレッドを立ててもInvoke等で
    > 結局メインスレッドにアクセスする必要があり,あまり意味がない気がしました.

    描画する部分が極端に重いのであれば、そうなるかもしれません。
    しかし、そういった場合は Application.DoEvents を使っても似たようなものです。

    ワーカースレッドでは受け取ったデータの解析、描画に必要なデータ生成までとし、実際の描画はメインスレッドに Invoke なり、BeginInvoke なりを使うか、Invalidate メソッドを呼ぶだけにして後でくる Paint イベントで描画するかでしょうか。
    ただ、スレッド間で同期をうまく取らないと、描画がずれる、データが上書きされるなどの問題が発生する可能性があります。


    > イベント駆動については勉強不足でよくわからないので少し調べてみます.

    私がイベント駆動といったのは、「データを受け取った」と言ったようなイベントを受けて必要な処理をすることです。
    While ループで待つ代わりに、一度処理するごとにイベントハンドラから抜けて、次のイベントを待つ形です。

    今回の事例に使えるかどうかまでは調べていません。
    (データ受信完了、データ受信可能などのイベントを起こす仕組みがないとできない)
記事No.56168 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56180  Re[4]: 本スレッドが稼働しているときの別スレッドでのボタン操作
□投稿者/ anny -(2011/01/03(Mon) 16:47:35)
    2011/01/03(Mon) 17:26:58 編集(投稿者)
    2011/01/03(Mon) 17:26:53 編集(投稿者)

    Azulean様,回答ありがとうございます.

    > ワーカースレッドでは受け取ったデータの解析、描画に必要なデータ生成までとし、実際の描画はメインスレッドに Invoke なり、BeginInvoke なりを使うか、Invalidate メソッドを呼ぶだけにして後でくる Paint イベントで描画するかでしょうか。
    > ただ、スレッド間で同期をうまく取らないと、描画がずれる、データが上書きされるなどの問題が発生する可能性があります。

    質問した箇所とは別の部分でInvokeを使って描画しているのですが,仰るとおりにスレッド間でうまく同期が取れなかったので結局(描画に必要なデータ生成+実際の描画)をInvokeで行っています.
    描画部分のみをInvokeで行いたいのですが難しいです.

    > 私がイベント駆動といったのは、「データを受け取った」と言ったようなイベントを受けて必要な処理をすることです。
    > While ループで待つ代わりに、一度処理するごとにイベントハンドラから抜けて、次のイベントを待つ形です。

    現状では自分でイベントを記述することができない状態なので,勉強してから今回のケースに対応できるかどうか試してみます.

    今回はApplication.DoEventsを使って最初の質問部分に対応したいと思います.
    問題が起きないことを祈りつつ…
    ありがとうございました.
記事No.56168 のレス / END /過去ログ94より / 関連記事表示
削除チェック/

■56181  ラベルにマウスで描画するとずれる
□投稿者/ anny -(2011/01/03(Mon) 17:42:06)

    分類:[C#] 

    開発環境
    Windows7 
    VisualC# 2008

    昨日もお世話になりました.
    C#でラベルにドラッグしている間のマウスの軌跡を描画したいのですがずれてしまいます.
    実際に描画したい場所からx方向が300,y方向が100ほど離れています.目分量ですが.
    ピクチャボックスだとうまく行くのですが…
    このようになる原因は何だと考えられるでしょうか?
    ラベルを用いていてもマウスでクリックした場所はちゃんと取得できているようです.

    よろしくお願いします.

    以下用いたソース(緑のバイク ★ 初めてのC# のピクチャボックスをラベルに変えたもの)
    Graphics grfx ; // Graphics オブジェクト
    int start = 0 ; // 1 = 描画中
    int startX ; // Line X 起点
    int startY ; // Line Y 起点

    private void Form1_Load(object sender, System.EventArgs e)
    {
    // Graphics オブジェクトの取得
    label1.Image = new Bitmap(Screen.PrimaryScreen.WorkingArea.Width,
    Screen.PrimaryScreen.WorkingArea.Height) ;
    grfx = Graphics.FromImage(label1.Image) ;
    }

    private void label1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
    start = 1 ;
    startX = e.X ;
    startY = e.Y ;
    }

    private void label1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
    {
    start = 0 ;
    }

    private void label1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
    {
    if (start == 0) return ;
    grfx.DrawLine(p, startX, startY, e.X, e.Y) ;
    startX = e.X ;
    startY = e.Y ;
    label1.Refresh() ;
    }
親記事 /過去ログ94より / 関連記事表示
削除チェック/

■56182  Re[1]: ラベルにマウスで描画するとずれる
□投稿者/ Azulean -(2011/01/03(Mon) 19:13:22)
    Label は Label のサイズより大きなサイズの画像が設定されている場合、できるだけ中央に表示しようとします。
    このため、Label の (0, 0) と画像の (0, 0) はずれてしまいます。

    このコードを一番手っ取り早く現状に合わせるには、Bitmap のサイズを label1.Width, label1.Height で作ることです。
記事No.56181 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56183  Re[2]: ラベルにマウスで描画するとずれる
□投稿者/ anny -(2011/01/03(Mon) 19:21:33)
    Azulean様,昨日に引き続き回答ありがとうございます.

    > このコードを一番手っ取り早く現状に合わせるには、Bitmap のサイズを label1.Width, label1.Height で作ることです。

    label1.Widthとlabel1.Heightでサイズを指定すると思いどおりに動きました.
    アドバイスありがとうございました.助かります.
記事No.56181 のレス / END /過去ログ94より / 関連記事表示
削除チェック/

■56189  コンボボックス
□投稿者/ YUKI -(2011/01/04(Tue) 16:00:18)

    分類:[VB.NET/VB2005 以降] 

    こんにちは。
    コンボボックスに時間を格納したいのですがやり方が
    分かりません。
    開始時間と終了時間が指定されていて30分毎に時間を
    格納したいと考えています。
    よろしくお願いしたします
親記事 /過去ログ94より / 関連記事表示
削除チェック/

■56190  Re[1]: コンボボックス
□投稿者/ shu -(2011/01/04(Tue) 16:07:16)
    No56189 (YUKI さん) に返信
    > こんにちは。
    > コンボボックスに時間を格納したいのですがやり方が
    > 分かりません。
    > 開始時間と終了時間が指定されていて30分毎に時間を
    > 格納したいと考えています。
    > よろしくお願いしたします
    
    dtStart as Date : 開始時間
    dtEnd as Date : 終了時間
    cbo1 as ComboBox : 対象コンボ
    
    
    Dim dtTmp as Date = dtStart
    Do While dtTmp<=dtEnd
        cbo1.Items.Add(dtTmp.ToString("HH:mm"))
        dtTmp = dtTmp.AddMinutes(30)
    Loop
    
    
    直接書いたコードなので検証してません。
    
    
記事No.56189 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56193  Re[2]: コンボボックス
□投稿者/ YUKI -(2011/01/04(Tue) 16:49:06)
    No56190 (shu さん) に返信
    > ■No56189 (YUKI さん) に返信
    >>こんにちは。
    >>コンボボックスに時間を格納したいのですがやり方が
    >>分かりません。
    >>開始時間と終了時間が指定されていて30分毎に時間を
    >>格納したいと考えています。
    >>よろしくお願いしたします
    >
    > dtStart as Date : 開始時間
    > dtEnd as Date : 終了時間
    > cbo1 as ComboBox : 対象コンボ
    >
    >
    > Dim dtTmp as Date = dtStart
    > Do While dtTmp<=dtEnd
    > cbo1.Items.Add(dtTmp.ToString("HH:mm"))
    > dtTmp = dtTmp.AddMinutes(30)
    > Loop
    >
    >
    > 直接書いたコードなので検証してません。
    >
    >

    ありがとうございます。
    目的の動きを実装できそうです。
記事No.56189 のレス / END /過去ログ94より / 関連記事表示
削除チェック/

■56164  イベントログのイベントログ時間でソートして習得
□投稿者/ C##### -(2011/01/02(Sun) 17:09:21)

    分類:[C#] 

    C#の学習中です。

    宜しくお願い致します。

    イベントログを習得する際に
    System.Diagnostics.EventLog[] logs =
    System.Diagnostics.EventLog.GetEventLogs();

    foreach (System.Diagnostics.EventLog log in logs)
    {

    }
    で取得するとイベントログの記録された古いものから順に表示されてしまいます。
    新しいものからに順番を変えるにはどうしたらいいのでしょうか。

    いろいろ試行錯誤しましたが、うまくいきませんんでした。
    宜しくお願い致します。

    環境は.net3.5です
親記事 /過去ログ94より / 関連記事表示
削除チェック/

■56165  Re[1]: イベントログのイベントログ時間でソートして習得
□投稿者/ επιστημη -(2011/01/02(Sun) 17:56:05)
>
    > 新しいものからに順番を変えるにはどうしたらいいのでしょうか。
    
    配列のナカミを逆順にしたいのかしら。
    
    class Program {
      public static void Main() {
        int[] ar = { 1, 2, 3, 4, 5};
        System.Array.Reverse(ar); // ←コレで逆順
        foreach ( int item in ar ){
          System.Console.WriteLine(item);
        }
      }
    }
    
記事No.56164 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56166  Re[2]: イベントログのイベントログ時間でソートして習得
□投稿者/ C##### -(2011/01/02(Sun) 18:12:59)
    2011/01/02(Sun) 18:14:18 編集(投稿者)

    ご回答有難う御座います。
    すみません、配列を逆というか
            StringBuilder sb = new StringBuilder();
    foreach (System.Diagnostics.EventLogEntry ee in log.Entries)
    {
    sb.Append(ee.Message + "\n");
    }
    イベントログのEventLog.Entriesの中身を日付で降順にしたいです。
    たぶんなにもしないと昇順でメッセージが取得したため、逆でいいかもしれませんが、
    正しくは日付で降順にしたいです。

    おそらく
    System.Diagnostics.EventLog[] logs =
    System.Diagnostics.EventLog.GetEventLogs();
    でいうと
    logs.OrderByDescendingでEntri内を並び替えられないのかなと
    考えましたが、方法がわかりませんでした。

    No56165 (επιστημη さん) に返信
    > > 新しいものからに順番を変えるにはどうしたらいいのでしょうか。
    >
    > 配列のナカミを逆順にしたいのかしら。
    >
    > class Program {
    > public static void Main() {
    > int[] ar = { 1, 2, 3, 4, 5};
    > System.Array.Reverse(ar); // ←コレで逆順
    > foreach ( int item in ar ){
    > System.Console.WriteLine(item);
    > }
    > }
    > }
    >
記事No.56164 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56167  Re[3]: イベントログのイベントログ時間でソートして習得
□投稿者/ やじゅ -(2011/01/02(Sun) 20:06:30)
>
    No56166 (C##### さん) に返信
    > イベントログのEventLog.Entriesの中身を日付で降順にしたいです。
    
    LINQを使って、日時の降順にする。
    参考 http://www.hookedonlinq.com/EventLogViewerSample.ashx
    
    System.Diagnostics.EventLog eventLog = new EventLog();
    
    eventLog.Log = "Application";
    
    var sources = (from System.Diagnostics.EventLogEntry es in eventLog.Entries
                   orderby es.TimeGenerated descending
                   select es);
    
    
    // 問い合わせ結果の表示
    foreach (var src in sources)
    {
        Console.WriteLine(src.TimeGenerated + " " + src.Message);
    }
    
記事No.56164 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56169  Re[4]: イベントログのイベントログ時間でソートして習得
□投稿者/ C##### -(2011/01/02(Sun) 21:32:27)
    やじゅ様
    有難う御座います。まさにそのコードで解決できました
    Linqでできたんですね。勉強になりました。

    実現できたので解決なんですが
    OrderByDescendingを使って同じことはできるんでしょうか?
    これで、デリゲートやラムダを使って書いてみたんですが
    うまくいかずで、どうしたらいいのか。。。。

    よければご教授下さいませ。
記事No.56164 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56171  Re[5]: イベントログのイベントログ時間でソートして習得
□投稿者/ やじゅ -(2011/01/02(Sun) 22:29:13)
>
    No56169 (C##### さん) に返信
    > OrderByDescendingを使って同じことはできるんでしょうか?
    
    System.Diagnostics.EventLog eventLog = new EventLog();
    
    eventLog.Log = "Application";
    
    var sources = eventLog.Entries.Cast<EventLogEntry>()
                .OrderByDescending(o => o.TimeGenerated); 
    
    // 問い合わせ結果の表示
    foreach (var src in sources)
    {
        Console.WriteLine(src.TimeGenerated + " " + src.Message);
    }
    
記事No.56164 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56191  Re[3]: イベントログのイベントログ時間でソートして習得
□投稿者/ shu -(2011/01/04(Tue) 16:14:32)
    No56166 (C##### さん) に返信

    > ご回答有難う御座います。
    > すみません、配列を逆というか
    >         StringBuilder sb = new StringBuilder();
    > foreach (System.Diagnostics.EventLogEntry ee in log.Entries)
    > {
    > sb.Append(ee.Message + "\n");
    > }
    > イベントログのEventLog.Entriesの中身を日付で降順にしたいです。
    > たぶんなにもしないと昇順でメッセージが取得したため、逆でいいかもしれませんが、
    > 正しくは日付で降順にしたいです。
    取得したデータが希望の並び順と逆順に並んでいるんだからεπιστημηさんの言うように
    Reverseした方が効率いいと思います。試してみて結果が違っていたのですか?
記事No.56164 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56192  Re[4]: イベントログのイベントログ時間でソートして習得
□投稿者/ やじゅ -(2011/01/04(Tue) 16:30:01)
>
    No56191 (shu さん) に返信
    > Reverseした方が効率いいと思います。試してみて結果が違っていたのですか?

    System.Diagnostics.EventLogEntry型なので、Reverse出来なかっただけかも。
記事No.56164 のレス /過去ログ94より / 関連記事表示
削除チェック/

■56195  Re[5]: イベントログのイベントログ時間でソートして習得
□投稿者/ shu -(2011/01/04(Tue) 17:31:43)
    No56192 (やじゅ さん) に返信
    > ■No56191 (shu さん) に返信
    >>Reverseした方が効率いいと思います。試してみて結果が違っていたのですか?
    > 
    > System.Diagnostics.EventLogEntry型なので、Reverse出来なかっただけかも。
    > 
    そういうことなのかな?
    
    それなら
    
           System.Diagnostics.EventLogEntryCollection ents = log.Entries;
           StringBuilder sb = new StringBuilder();
           for (int idx = ents.Count - 1; idx>=0 ; idx--)
           {
               System.Diagnostics.EventLogEntry ent = ents[idx];
               sb.AppendLine(String.Format("{0}", ent.Message));
           }
    
    こんな感じなら大丈夫?
記事No.56164 のレス /過去ログ94より / 関連記事表示
削除チェック/

<前の20件 | 次の20件>

<< 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 >>

ヒット件数が多いので過去ログ1〜94 までの検索結果 / 過去ログ95からさらに検索→

パスワード/

- Child Tree -