• ベストアンサー

タスクバーに表示される文字を更新したい!

いつもお世話になっております! C#.NetでWindows Formアプリケーションを作成しております。 別Threadにて処理をしている進捗状況(%)を、Form.Textに表示更新しているのですが、フォームのタイトルバーは更新されますが、タスクバーの表示文字列がフォームを最小化などを行わないと更新されません。 タスクバーの文字列をアプリケーション側から更新する事ができるのでしょうか? ご回答よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • luka3
  • ベストアンサー率74% (316/423)
回答No.4

こちらでも症状が再現できました。 いろいろ手がかりを探っているうちに、海外でやっと似たような質問に出会いました。 (当初から海外は調べていたのですが検索ワードがうまくはまらなかった) ・c# - How to force a redraw of my application's entry in the taskbar? - Stack Overflow http://stackoverflow.com/questions/380380/how-to-force-a-redraw-of-my-applications-entry-in-the-taskbar これをざっと見たところ、 「ウインドウタイトルが100ミリ秒以下で更新されるとタスクバーには反映されない」 というニュアンスのようです。 これをヒントにNo.3のプログラムをこのようにしてみました。 for (int i = 1; i <= 100000; i++) {  SetText((i/10000).ToString() + ":" + msg);  //System.Threading.Thread.Sleep(1000); } たくさんのループで毎回タイトルを書き換えるけども、実質10種類だけ、というものです。 こうすることでタイトルの変化に間隔が生まれタスクバーにもすべて反映されました。 こうしたことから私の考える回避策は ・毎回更新せず、時刻をミリ秒で取得して、ある程度の間隔があいてから更新するようにする ・タイマーを利用して一定間隔で更新するようにし、スレッドではタイトル文字列をどこかに保存するのみとする ・タスクバーにWM_PAINTを送ってみる? といったところですね。 ちなみに、スレッド\非スレッドでの確認のためThread...Start()を使わずに 直接ThreadTestを呼び出してみたら処理速度が体感で10倍くらい違いました。 Invokeが遅いのかな?

kamepanman
質問者

お礼

ありがとうございます! リンク先を見ると、同じような流れの回答でちょっと笑いましたw 更新が頻繁すぎるとタスクバーの更新を諦めるということですね。 回避策のうち一番処理が早いのを採用してみます。 よくよく考えると、100ミリ秒ほどの高速でタスクバーを更新する必要なんてありませんね(汗 >ちなみに、スレッド\非スレッドでの確認のためThread...Start()を使わずに >直接ThreadTestを呼び出してみたら処理速度が体感で10倍くらい違いました。 >Invokeが遅いのかな? こちらを試してみましたが、私の環境で計測してみましたが、処理速度には差がありませんでした。 ThreadTestには、this.Update();などがないのに、タイトルの表示が更新されていたのが驚きでした! いろいろと試していただいてありがとうございます! 勉強になりました!

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • luka3
  • ベストアンサー率74% (316/423)
回答No.3

何度もすいません。 想像で回答しても仕方が無いのでVS2010のC#をインストールしてやってみました。 結果は、新規スレッドからタイトルを変更すると即座にタスクバーへ反映されました。 テストはFormにボタンを1個置いて以下のようにしました。 WinXP SP3(32bit)とWin7 SP1(64bit)でテストしました。 private void button1_Click(object sender, EventArgs e) {  new Thread(new ThreadStart( delegate {    ThreadTest("TEST SetText");    })).Start(); } private delegate void SetTextCallback(string msg); private void SetText(string msg) {   if (this.InvokeRequired)     this.Invoke(new SetTextCallback(SetText), new object[] {msg});   else Text = msg; } private void ThreadTest(string msg) {  for (int i = 1; i <= 10; i++) {   SetText(i.ToString() + ":" + msg);   System.Threading.Thread.Sleep(1000);  }  SetText("END"); }

kamepanman
質問者

お礼

※Threadまわり書き換えなくてもいけますね。勘違いでした。 同じコードで試してみたところ、問題なく更新されました。 private void ThreadTest(string msg) {  for (int i = 1; i <= 10; i++) {   SetText(i.ToString() + ":" + msg);   System.Threading.Thread.Sleep(1000);  }  SetText("END"); } のSystem.Threading.Thread.Sleep(1000); があると更新されることも分かりました。 私の環境ですと最低でも200ミリ秒はないと、全てが反映されず、100ミリ秒で間が飛び、10程度だと1つめが更新され、次はENDが表示される状態です。 ただ、処理の量が多いので、スレッドをSleepしてしまうと、処理時間が延びてしまいます・・・。

kamepanman
質問者

補足

何度もありがとうございます!! わざわざインストールまでしていただいてスミマセン。 1TEST SetText~10TEST SetTextまでタスクバーに反映されたということでしょうか? 当方の環境がXP SP2 VS2008C#EEなので、同じコードのThreadまわりを書き換えて、試してみます!

全文を見る
すると、全ての回答が全文表示されます。
  • luka3
  • ベストアンサー率74% (316/423)
回答No.2

先日は的外れな回答をしてすみませんでした。 タスクバーと書いてあるのに勝手にステータスバーと勘違いしていました。 ウインドウタイトルとタスクバーにずれが生じているということですよね。 ちょっと調べてみましたが似たような症状というのは見つけられませんでした。 原因として思いつくのは 「Formで作られたウインドウとは別にもう一段上に目に見えないメインウインドウがいて、  タスクバーにはこのウインドウタイトルが表示されている。  通常はForm.Textの文字列をコピーしているがスレッド処理の際は間に合っていない」 というものですが、もしこれが正しい場合の対処法は 見えないウインドウを探して、APIのSetWindowTextを呼び出すとか、 メインのDoEventsを呼びだしてみるとか、ですかね。 Spy++とかでウインドウを調べてみることはできますでしょうか。

kamepanman
質問者

お礼

ありがとうございます! お礼前に、No.3の回答を頂きましたので、順序が変ですがw 目に見えないメインウインドウが見つけられず、あまり検証できませんでした。 知識が足りず、ついて行けていない状態でした。

全文を見る
すると、全ての回答が全文表示されます。
  • luka3
  • ベストアンサー率74% (316/423)
回答No.1

こんにちは。 C#は興味がありつつも実際にはやったことがないので 過去の経験から想像しての回答です。 ウインドウの描画の更新、といえばInvalidateです。 .NETではRefreshやUpdateもあるようですので、こちらを参考に試してみてください。 ・Refresh、Update、Invalidateメソッドの違い: .NET Tips: C#, VB.NET http://dobon.net/vb/dotnet/control/refreshupdateinvalidate.html また更新メッセージが発行されても、処理が別スレッドに取られていて処理できない、 というのも考えられますので、そういう場合はDoEventsを呼ぶといいようです。 ・EZ-NET: ステータスバーに進捗状況を表示する - Visual C# プログラミング http://program.station.ez-net.jp/special/handbook/csharp/control/StatusBar/progress.asp

kamepanman
質問者

お礼

ありがとうございます。 実際にフォームタイトルの更新は、 this.Invoke((MethodInvoker)delegate() { this.Text = str; this.Update(); }); としていますので、フォーム自体は更新されています。 DoEvents は同一スレッドでの話ではないでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • タスクバー内の表示について。

    はじめまして、viclifeと申します。よろしくお願いいたします。 タスクバー内で、今使用中のアプリケーションを最小化した場合、 今まではそのアプリケーションが表示されていたのですが、 それが表示されなくなってしまいました。 ですから、今は、いちいちタスクマネージャーから開いています。 タスクバー内に、今使用中のアプリケーションを表示するには、 どのようにしたらいいのでしょうか? よろしくお願いします。

  • タスクバーに表示されるアイコンを隠したいのですが

    こんにちはnekocyanです。 宜しくお願いします。 今回教えて頂きたいのは、あるアプリケーションの ウインドウを最小化したときに通常だとアイコンが タスクバーに表示されますが、これを隠すことは 出来るのでしょうか? 例:タスクマネージャーのオプション   最小化時に隠す ような感じです。 隠したいアプリには、最小化したときにタスクバー のアイコンを隠すようなオプションはありません。 OSはwindows2000です。 再度表示したいときは、タスクマネージャーを 使いたいと考えています。 設定でも、何かのソフトを使うのでもいいのです が何か方法をご存知の方がおられましたら、是非 ご教授ください。 出来ましたら、アプリケーション毎に設定できると 嬉しいのですが・・・

  • タスクバーに表示されない

    FMVでタスクバーにアプリケーションが表示されない。最小化したら画面から消える 元にするにはどうしたらいいですか。よろしくお願いします。

  • タスクバーにフォーム名を表示させたくない

    タスクバーにアクセスのアイコンとファイル名とフォーム名が表示されるのですが、 フォーム名を非表示にする方法はありますか? アクセスファイルは複数開いているのですが 書類というファイルだけ、フォーム名が表示されます。 アプリケーションタイトルには、「書類」と入れています。 タスクバーのアクセスのアプリケーションをクリックしたときに、 フォーム名は表示させたくないのですが、その方法を教えてください。

  • テキストボックスに変数を表示させたい

    access2003です。 フォーム1にテキスト0を配置し vbaで Private Sub Form_Open(Cancel As Integer) Dim 文字列 As String 文字列 = "a" End Sub と作成しました。 このときフォーム1をダブルクリックして開いた時に テキスト0に文字列に代入した変数を表示させるにはどうすればいいのでしょうか? テキスト0のコントロールソースに =[文字列] とやっても #Name? になってしまいます。 どうすれば読み取った変数をテキスト0に表示させることが可能なのでしょうか? よろしくお願い致します。

  • C# タスク非表示でタイトルバーは表示する

    前略 ・C#の初心者です。 ・タスクバーは下記のプログラムで非表示とすることができますが、同時にタイトルバーも消えてしまいます。タスクバーは非表示で、右端に閉じる・最大化・最小化アイコン("X"、 "□"、"_")のないタイトルバーを表示したいのですが、その方法をおしえてください。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace noTaskbar { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.FormBorderStyle = FormBorderStyle.None;//タイトルバー&タスクバー非表示 this.WindowState = FormWindowState.Maximized;// } } } 以上、よろしくお願いします

  • 立ち上げているアプリケーションがタスクバーに表示されない

    タスクバーに現在立ち上げているアプリケーションのアイコンが全く表示されなくなってしまいました。 通常はアプリケーションを立ち上げたら、同時にそのアイコンがタスクバーに表示され、タスクバーでアクティブなウィンドウと非アクティブなウィンドウを切り替えられますが、それが全く表示されなくなりました。タスクバーを上下に拡大しても、中でマウスを左右にスライドさせても、どこにも隠れていません。 開いているウィンドウを小さくすると、後ろにある別のウィンドウが表示されますが、最小化すると、タスクバーの左あたりに吸い込まれるように消えてしまい、再表示する事ができません。それでも、タスクマネージャでは実行中のアプリケーションとして表示されており、そこから呼び出しや終了はできます。 No.1214674にも、今回の私のと同様の症状と思われる質問がありましたが、解決はされていないようでした。 今までこんな症状になった事はなく、何を調べても載っていないようで、大変困っています。どうか解決法をお教え下さい。

  • タスクバー

    普通、ウィンドウを最小化するとタスクバーだけにそのアプリケーションが表示されます。 先日から、Outlook2003の調子がおかしく、最小化するとタスクバーから消えてしまいます。 しかし、Outlook2003が終了したわけではなく、Outlook2003のアイコンをクリックすると復帰します。 そのほかのアプリケーションは正常です。 どうしてなのでしょうか? OSはXP Professional SP2です。

  • ボタンでテキスト領域に文字列を表示させたい

     非常に初歩的なことでしょうが、ネットや書籍を見ても以下の ことが分かりません。お教えください。 ボタンを押すことで目的の文字列をフォームのテキスト領域に表 示したいのです。例えば、 <form> <input type="button" onClick=???? value="Click!"> <input type="text" size="10"> </form>  という内容で、onClickの右側をどう書いたらよいか分かりません。 document.write("文字列")だと、画面が更新されてボタンやテキ スト領域まで消えてしまうので、だめです。本を参考にして、 「document」のところを「document.form.txt」に変えればよい のかと考えたのですが、それではエラーがでます。  よろしくご教示ください。

  • ダイアログの最小化

    VB.NET 2003を使ってます。 フォームが3つあってそれぞれ重ねて(Form1でForm2を表示し、Form2でForm3を表示するという意味)モーダルで表示しておいて、Form3のダイアログの最小化ボタンを押したときに、このアプリの全てのウインドウ(Form1とForm2も含む)を最小化したいのです。 普通だとForm3だけ最小化されてしまいますよね。 理想の動きとしては、windows標準の”デスクトップの表示”の機能を、自分が作ったアプリだけを最小化したようなイメージです。 タスクバーのアプリをクリックすればウィンドウが復元されて便利です。

このQ&Aのポイント
  • 無線LAN環境でネットワークを切断して、USBケーブルでPCより印刷するとプリントエラーとなります。
  • 無線LANでは印刷可能です。
  • 設定が必要でしょうか。
回答を見る