DOBON.NETプログラミング道掲示板

■ 「新規作成」から投稿できます。
■ マルチポストされた投稿を見つけたときは、その投稿に返信することによりご報告ください。その際は匿名で投稿し、マルチポストされている場所を併記してください。
■ スパム対策のため、メールアドレスの先頭に"_"という文字が付加されています。
RSS 2.0 RSS 2.0 | RSS 0.91 | 携帯電話用 | 自分専用のアイコンを使用するには | 掲示板への要望 | 管理人に連絡 | お気楽掲示板
■ 24時間以内に作成されたスレッドは New で表示されます。
■ 24時間以内に更新されたスレッドは UpDate で表示されます。

記事リスト ( )内の数字はレス数
NomalDataGridViewの複数行選択で歯抜け選択を無効にしたい(2) | Nomal証券会社へのログイン(1) | Nomalユーザーフォームに埋め込んだAutoCADの変化を捉える(0) | Nomalシステムドライブ以外へのページング設定が反映されない(5) | Nomalブラウザでコピーした透過PNGを貼り付けたい(4) | Nomalforeachでループ回数を取得(2) | Nomalbitmapが保存できない(2) | Nomal特定ピクセルで画像を読み込みたい(2) | NomalDataGridViewでAlt+Enterで改行したい(2) | Nomal全角シフト中にアクセスキーが効かない(5) | NomalDataAdapter.Updateで構文エラー(6) | Nomal抽象クラスで実装したクラスの情報を知る(3) | NomalProcessクラスからbatファイル実行後、KILLできない(2) | Nomal画面遷移(モーダルとモードレス)(2) | Nomal兆億万表記の文字列を数値に変換できる?(3) | NomalGetDirectoriesでルートを指定するとエラーになる(3) | NomalLinqにおける明示的型指定の方法(3) | Nomal2つのradの数値から1つの角度を求めるコードを改善できますか?(C++)(2) | Nomalコンソールアプリで、WebView2の利用(2) | NomalEntity Frameworkは、使えるか?(2) | Nomalデータベースからのテーブル名一覧の効率的な取得方法(3) | NomalC#のlong型でオーバーフローになる(2) | Nomal正規表現のパターン表記方法(2) | NomalWebView2によるスクレ―ピング(4) | Nomalこういた物を作れますか?(2) | Nomalツールボックスにtableadapterが表示されない(1) | NomalC# Chart X軸上のグラフ表示(3) | NomalVB.NETでBluetoothデバイスの電池残量を取得する方法(3) | Nomalクリスタルレポート 明細部のサブレポート(0) | Nomal重なったPictureBox同士を透過する方法(7) | NomalWindowsフォームデザイナについて(3) | NomalVB.NETからcmdでpingを実行した時の結果(5) | Nomalvb.netでExcelファイル操作(7) | Nomalvb.netでのExcelファイルそうさ(2) | Nomalキーボード+バーコードでキーボード入力を無効にしたい(6) | Nomalファイルとして配置したマニフェストを優先したい(2) | NomalTabPageの背景色(5) | NomalVB2022でクリスタルレポートが開けない(2) | NomalC#でJpeg圧縮のTiffファイルを作成したい(4) | Nomalエクセルのみ監視ができない(2) | NomalDataGridViewのVirtualModeを有効した場合の実装方法(4) | NomalExcelの数値 -> 日付みたいな関数?(2) | NomalDrawstringでの透過文字作成(3) | Nomaljumbo icon(256x256)が存在するか知る方法(6) | NomalSpinWait()を使う理由(2) | Nomalantecedentってなんですか?(2) | Nomalワンタイムパスワードのサイトに自動ログインしてアクセストークンを得る(3) | Nomalstyle.displayだと効率悪いから違うやり方をしたいです。(5) | Nomalテーブルを順番通りに直すプログラムを外部で読み込めるようにしたいです。(4) | NomalJSONの複雑な入れ子内部の値を取りたい。(3) | Nomalグリッド表示レコードをJSONに変換(5) | Nomalシステム時計の設定(3) | NomalSeleniumで開いているページのTableを編集したい(5) | Nomalソケット通信入門 ひらがな(4) | NomalVisual Basicでエラーが出る(3) | Nomalインストーラにて、ローミングフォルダにファイルを配置したい(0) | NomalRGB値の所得(2) | NomalVB.net からAccessDBへの接続(2) | Nomal時間変数(文字列)の扱い(4) | Nomal画像のスクロール(6) | Nomalタイマーの一括処理(6) | NomalTreeViewとDataGridViewのスクロールを同期(シンクロ)させたい(4) | NomalTreeViewの現在位置とDataGridViewの現在位置を合わせたい(7) | Nomalフォームのリサイズ時にDataGridViewが再描画されない(4) | NomalPDFをフォーム上で表示させる方法につきまして(4) | NomalPictureBoxの画像を連続保存(11) | NomalテキストボックスのValidatingイベントよりも先に発生するボタン発生イベントは何でしょう?(2) | Nomal継承元フォームで各フォームのボタン動作を検知したい(3) | NomalWindowsエクスプローラからのドラッグ&ドロップ(2) | Nomalラジオボタンの一括設定(7) | Nomalクリックイベントでexeを作成できるか(2) | Nomal作成した白黒画像をWordに貼り付けてから「図として保存」(8) | Nomalアセンブリ情報が載らない(1) | NomalRichTextBoxのテキストをpictureBOXへ(12) | Nomalc#で日付型の定義の仕方で質問があります。(2) | Nomal先頭に空白(スペース)があるファイルを読み込んでRichTextBoxへ書き出すとスペースが削除える(6) | NomalExcel Com オブジェクトの増殖(13) | Nomal二次元マップから値の取得(1) | NomalアプリでHDMIへ出す解像度を変えたい(4) | NomalDataGridViewのドロップダウンリストの表示と選択後の値を分けたい(1) | Nomal列車の時間ごとの位置情報を表示したいです。(2) | Nomal画像の中心を基点に回転(4) | NomalDataGridViewの行ヘッダーに行番号を表示した時のエラー(4) | NomalタッチキーボードでIMEを自動で切替えたい(6) | NomalVSTOによるエクセルアドインのインストーラーでのアップデート(1) | NomalMP4動画を再生する方法について(5) | NomalVB.NetでVB6.0と同じFontを指定しても同様に印刷されない(9) | NomalLabelで文字単位の背景色(7) | NomalLableのカラー色を文字変数から変更したい(5) | NomalUrlにアクセスするとダウンロードされるファイルを捕まえる(2) | Nomalタブレット等でスワイプによるスクロールを実装(2) | NomalTEXTBOXのプロパティを文字列に(7) | NomalPDFをフォーム上で表示させる方法につきまして(6) | NomalChart X軸上の描画を切り替えたい(0) | NomalRichTextBoxへのドラッグ&ドロップしたExcelファイルの扱い(3) | Nomal特定のPCだけ発生する「パディングは無効なので削除できません」のエラーの原因(6) | NomalASP.NET WebApi内でXmlReader.Create(url)がタイムアウトする(4) | NomalDatagridViewでファンクションキーを止めたい(5) | Nomal表示動作が重くなる(3) | NomalDataGridViewの特定セルにボタンを配置する方法(5) |



■記事リスト / ▼下のスレッド
■35316 / 親記事)  PictureBoxの画像を連続保存
□投稿者/ ま〜 一般人(38回)-(2023/01/10(Tue) 19:41:27)
  • アイコン環境/言語:[VS2022 VB] 
    分類:[.NET] 

    こんばんわ
    また困った事がありましてお教え願います
    15個のPictureBoxの画像をグルグル回してファイルに落としたいのですが
    どうも上手くできないのです。
    ファイル保存の方は問題なく出来ると思うのですが
    PictureBoxからイメージを取ってきて受け渡しをどう考えれば宜しいでしょうか?
    宜しくお願いしまうす

違反を報告
引用返信

▽[全レス11件(ResNo.7-11 表示)]
■35323 / ResNo.7)  Re[7]: 複数のPictureBox画像を複数のファイルへ保存したい
□投稿者/ ま〜 一般人(42回)-(2023/01/12(Thu) 14:13:11)
  • アイコンいつもありがとうございます
    フィールド変数の件は棚ぼたです。出来ないと思ってました。助かります。

    本題ですが先のコードでわDisposeした方が良いのか程度で書いてました
    Form LoadでDisposeしてますがボタンクリックでTextBoxから画像を生成して各PictureBoxに書いてますので問題ないと解釈していました
    今二つの問題に当たっています。スレッドを分けなかったのは同じ要因かなと思ってです。

    流れ RichTextBoxへ文字入力 ⇒生成⇒ PictureBox16 ⇒サイズを変えてコピー⇒ 各PictureBox ⇒ すべてのPictureBoxの画像をファイル保存


    ――――――――ボタン@――――――――ー
    Dim bmp = CreateBitmapFromControl(Rbox(PageNo))
    If PictureBox16.Image IsNot Nothing Then
      PictureBox16.Image.Dispose()
    End If

    ‘P PageNo←どのPictureBoxを操作するか
    PictureBox16.Image = bmp ← 自動生成されたイメージが入っている
    ‘ピクチャ1−15へ各個転送
    Dim Picture() As PictureBox = {PictureBox1, PictureBox2, PictureBox3, ・・・・・PictureBox15} 
    Picture(PageNo).Image = PictureBox16.Image

    これは同じ画像を各PictureBoxへ書いたと同じ扱いになりますか?一旦PictureBox16経由で各PictureBoxへ作画されています
    これがやっては駄目な事でしょうか?

    最後の書いたPictureBoxをBで保存する事は出来ました。
    それ以外のPictureBox以外でBのコードを実行するエラーとなる

    ―――――――Bエラーになる箇所――――――――――
    Picture(PageNo).Image.Save(PicturePath"MojiGAZou1.bmp",System.Drawing.Imaging.ImageFormat.Bmp)


    Imageは使わない方がよいのでしょうか?

    ―――――――――ボタンA――――――――――――
    試してみました

    Dim Picture() As PictureBox = {PictureBox1, PictureBox2, PictureBox3, PictureBox4, PictureBox5}
    For i As Byte = 0 To 4
    Picture(i).Size = New Size(Picture(i).Size.Width, 320)
    Picture(i).Size = New Size(Picture(i).Size.Height, 160)
    Picture(i).SizeMode = PictureBoxSizeMode.Zoom
    Picture(i).Image = Image.FromFile(PicturePath + "MojiGAZou" & CStr(i + 1) & ".bmp")
    Next

    Me.PictureBox1.Image.Save(PicturePath + "MojiGAZou1.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    Me.PictureBox2.Image.Save(PicturePath + "MojiGAZou2.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    Me.PictureBox3.Image.Save(PicturePath + "MojiGAZou3.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    Me.PictureBox4.Image.Save(PicturePath + "MojiGAZou4.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    Me.PictureBox5.Image.Save(PicturePath + "MojiGAZou5.bmp", System.Drawing.Imaging.ImageFormat.Bmp)

    これもPictureBox1.のSaveの所でエラーとなります。こんな事は出来ない?

    以下はエラーの内容です

    System.Runtime.InteropServices.ExternalException
    HResult=0x80004005
    Message=GDI+ で汎用エラーが発生しました。
    Source=System.Drawing
    スタック トレース:
    at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
    at System.Drawing.Image.Save(String filename, ImageFormat format)
    at Test.文字編集Form.Button18_Click(Object sender, EventArgs e) in C:\Users\userMM\OneDrive\Test\文字編集Form.vb:line 232
    at System.Windows.Forms.Control.OnClick(EventArgs e)
    at System.Windows.Forms.Button.OnClick(EventArgs e)
    at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    at System.Windows.Forms.Control.WndProc(Message& m)
    at System.Windows.Forms.ButtonBase.WndProc(Message& m)
    at System.Windows.Forms.Button.WndProc(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    at Test.My.MyApplication.Main(String[] Args) in :line 83


    Disposeする必要は無いので何か良い方法はありますか?

    あと

    >No35282 の KOZ さんの実装パターンに相当しますね。
    >
    > PictureBox1.Image?.Dispose() '処分
    > PictureBox1.Image = Nothing '解放

    とありますがこれはどの様な意味ですか?

    以上、長々とすみません

違反を報告
引用返信
■35324 / ResNo.8)  Re[8]: 複数のPictureBox画像を複数のファイルへ保存したい
□投稿者/ 魔界の仮面弁士 大御所(1516回)-(2023/01/12(Thu) 16:00:58)
  • アイコンNo35323に返信(ま〜さんの記事)
    > 本題ですが先のコードでわDisposeした方が良いのか程度で書いてました
    でわ→では


    > If PictureBox16.Image IsNot Nothing Then
    >   PictureBox16.Image.Dispose()
    > End If
    上記は『PictureBox16.Image?.Dispose()』の一行で書けます。
    https://learn.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/operators/null-conditional-operators

    そして、Disposed 状態のオブジェクトを参照し続けた状態にするのは問題があるため、
    PictureBox16.Image には直ちに、Nothing (あるいは別の画像)を代入しなおさねばなりません。

    ただし本来は、別の画像(あるいはNothing)を割り当ててから元の画像を Dispose した方が望ましいです。


    > PictureBox16.Image = bmp ← 自動生成されたイメージが入っている
    > Picture(PageNo).Image = PictureBox16.Image
    > これは同じ画像を各PictureBoxへ書いたと同じ扱いになりますか?

    一つの画像を複数の PictureBox から参照している状態になりますね。


    つまり、一枚の絵画を複数人で同時に鑑賞している状態に相当します。
    ということは、その絵画を破損させれば、他の閲覧者も破損した絵画を見ることになってしまいます。
    もしも閲覧者A が、自身が見ている絵画を破棄したとすれば、
    それは閲覧者B や C が見ている絵画も捨てられたことを意味します。

    Picture(0).Image を Dispose() した場合、
    Picture(1).Image も破棄されるので、ArgumentException 等になってしまう所以です。


    しかしあらかじめ、一枚の元絵を人数分複製しておき、それを閲覧させるようにすれば、
    元絵を破損させたとしても、各閲覧者の見ている画像が見えなくなることはありません。

    これはすなわち、
     Picture(PageNo).Image = DirectCast(PictureBox16.Image?.Clone(), Image)
    のようにしておく、ということです。それぞれの画像は元絵の複製にすぎないわけですから、
    Picture(0).Image を Dispose() したとしても、
    Picture(1).Image や PictureBox16.Image には影響がありません。


    > 一旦PictureBox16経由で各PictureBoxへ作画されています
    > これがやっては駄目な事でしょうか?
    何を経由させても構いません。
    変数であろうと PictureBox16.Image であろうと大丈夫です。

    問題になっているのは、PictureBox16 を経由させたことではなく、
    「使用中のオブジェクトを Dispose したこと」です。


    Picture(0) がその画像を使わなくなったとしても、他の PictureBox が
    同じインスタンスを使用しているのなら、Dispose してはいけません。
    捨てるなら、「誰も使わなくなってから」にしましょう。



    > ―――――――Bエラーになる箇所――――――――――
    > Picture(PageNo).Image.Save(PicturePath"MojiGAZou1.bmp",System.Drawing.Imaging.ImageFormat.Bmp)
    そもそも文法違反になるでしょうね。(^_^;)


    > Imageは使わない方がよいのでしょうか?
    いいえ。「誰かが使用している最中の Image を勝手に Dispose してはいけない」というだけです。

    「使い終わった Image は Dispose しなければならない」ルールであるのは確かですが、
    「私が使い終わったので、他の人が使っていたとしても勝手に捨ててしまおう」はルール違反です。


    > Dim Picture() As PictureBox = {PictureBox1, PictureBox2, PictureBox3, PictureBox4, PictureBox5}
    > For i As Byte = 0 To 4
    配列のインデックスは常に Integer 型です。Byte 型ではありません。

    Byte/SByte/Short/UShort は Integer 型への暗黙変換が可能なのでエラーにはなりませんが、
    わざわざ Byte 型を経由させると、無駄な変換処理が増えることになってしまいます。

    そのため普通は As Byte とはせず、「For i = 0 To 4」もしくは「For i As Integer = 0 To 4」と書きます。


    > Picture(i).Size = New Size(Picture(i).Size.Width, 320)
    > Picture(i).Size = New Size(Picture(i).Size.Height, 160)

    これって、
     Picture(i).Width = Picture(i).Size.Width
     Picture(i).Height = 320
     Picture(i).Width = Picture(i).Size.Height
     Picture(i).Height = 160
    に相当する処理ですよね。何故こんなことを…?

    幅と高さを指定するだけならば、
     Picture(i).Size = New Size(320, 160)
    では駄目なのでしょうか。SizeMode 指定のために必要だったとか?

    > Picture(i).Image = Image.FromFile(PicturePath + "MojiGAZou" & CStr(i + 1) & ".bmp")
    前 1 つが「+ 演算子」で、
    後 2 つが「& 演算子」なのは何故ですか?


    > Me.PictureBox1.Image.Save(PicturePath + "MojiGAZou1.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    > Me.PictureBox2.Image.Save(PicturePath + "MojiGAZou2.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    > Me.PictureBox3.Image.Save(PicturePath + "MojiGAZou3.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    > Me.PictureBox4.Image.Save(PicturePath + "MojiGAZou4.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    > Me.PictureBox5.Image.Save(PicturePath + "MojiGAZou5.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
    > これもPictureBox1.のSaveの所でエラーとなります。こんな事は出来ない?

    「Image が Dispose されていない」かつ「指定のパスに書き込みが可能」な状態にしておけば
    上記のコードでもエラーにはならないと思いますよ。

    仮に Dispose していなかったとしても、その画像が Image.FromFile で読み込まれていて、
    かつ、そのインスタンスがまだ破棄されていなかったとしたら、ファイルがロックされたままになるので
    また別のエラーを誘発する可能性がありますね。


    >> PictureBox1.Image?.Dispose() '処分
    >> PictureBox1.Image = Nothing '解放
    > とありますがこれはどの様な意味ですか?

    If PictureBox1.Image IsNot Nothing Then
     PictureBox1.Image.Dispose() '処分
    End If
    PictureBox1.Image = Nothing '解放

    という意味です。

    KOZ さんの書かれた No35282 の場合は、
     Dim bmp = CreateBitmapFromControl(RichTextBox1)
     If PictureBox1.Image IsNot Nothing Then
       PictureBox1.Image.Dispose()
     End If
     PictureBox1.Image = bmp
    ですね。

    いずれも、「bmp (または Nothing)を参照させる前に、以前の画像があれば Dispose する」という処理です。
    以前の画像を「処分してから解放」の順序になっているので、本当は「解放してから処分」の方が良いのですが。

    上記 No35282 のコードを「解放してから処分」にするのであれば
     Using PictureBox1.Image
      PictureBox1.Image = CreateBitmapFromControl(RichTextBox1)
     End Using
    または
     Dim oldImage = PictureBox1.Image
     PictureBox1.Image = CreateBitmapFromControl(RichTextBox1)
     oldImage?.Dispose()
    と書きます。自分は後者の方が好みですが、 No35282 のままでも問題はありません。
違反を報告
引用返信
■35330 / ResNo.9)  Re[9]: 複数のPictureBox画像を複数のファイルへ保存したい
□投稿者/ ま〜 一般人(44回)-(2023/01/16(Mon) 14:20:51)
  • アイコンいつもありがとうございます
    貴重なお時間割いて頂きご指導ありがとうございます
    今回も知らない事が多く大変勉強になりました
    最終目標はテキストから生成した画像を保存なので道のり長いですが宜しくお願いします

    テスト的にやって見た所。下記の2行目でエラーとなります。まさに沼です

      Me.PictureBox1.Image = Image.FromFile(PicturePath & "MojiGAZou1.bmp")
      Me.PictureBox1.Image.Save(PicturePath & "MojiGAZou1.bmp", System.Drawing.Imaging.ImageFormat.Bmp)

    2行目をコメントアウトして確認した所、表示はされてるのでファイルとかの問題ではなさそうです。。
    何か基本的なのが抜けてる気がしてきました。読み込んだだけでは保存出来ないのでしょうか?


    ーーーーーーーーーエラーの内容-----
    System.Runtime.InteropServices.ExternalException
    HResult=0x80004005
    Message=GDI+ で汎用エラーが発生しました。
    Source=System.Drawing

    余談ですが「は」「わ」の件ですが私も違和感あったのですが最近の若者からのメールが
    「わ」使う子が多くいつの間にか私も影響受けてるみたいです。(笑)

    あと+と&は修正途中でした。。意味はありません
違反を報告
引用返信
■35331 / ResNo.10)  Re[10]: 複数のPictureBox画像を複数のファイルへ保存したい
□投稿者/ 魔界の仮面弁士 大御所(1519回)-(2023/01/16(Mon) 16:14:25)
  • アイコン2023/01/16(Mon) 16:30:46 編集(投稿者)

    No35330に返信(ま〜さんの記事)
    > テスト的にやって見た所。下記の2行目でエラーとなります。まさに沼です
    >   Me.PictureBox1.Image = Image.FromFile(PicturePath & "MojiGAZou1.bmp")
    >   Me.PictureBox1.Image.Save(PicturePath & "MojiGAZou1.bmp", System.Drawing.Imaging.ImageFormat.Bmp)

    先の No35322 で紹介した通り、 Image.FromFile がファイルをロックしているためです。


    '駄目な例1
    PictureBox1.Image = Image.FromFile(bmpFile)
    'System.Runtime.InteropServices.ExternalException: 'GDI+ で汎用エラーが発生しました。'
    PictureBox1.Image.Save(bmpFile, System.Drawing.Imaging.ImageFormat.Bmp)


    '駄目な例2
    PictureBox1.Image = Image.FromFile(bmpFile)
    PictureBox1.Image.Dipose()
    'System.ArgumentException: '使用されたパラメーターが有効ではありません。'
    PictureBox1.Image.Save(bmpFile, System.Drawing.Imaging.ImageFormat.Bmp)


    '★修正例★
    PictureBox1.Image = Image.FromStream(New MemoryStream(File.ReadAllBytes(bmpFile)))
    PictureBox1.Image.Save(bmpFile, System.Drawing.Imaging.ImageFormat.Bmp)


    '駄目な修正例1
    PictureBox1.Image = Image.FromStream(New MemoryStream(File.ReadAllBytes(bmpFile)))
    PictureBox1.Image.Dipose()
    'System.ArgumentException: '使用されたパラメーターが有効ではありません。'
    PictureBox1.Image.Save(bmpFile, System.Drawing.Imaging.ImageFormat.Bmp)


    '駄目な修正例2
    Using stm As New FileStream(bmpFile, FileMode.Open, FileAccess.Read)
     PictureBox1.Image = Image.FromStream(stm)
    End Using
    PictureBox1.Image.Save(bmpFile, System.Drawing.Imaging.ImageFormat.Bmp)


    '駄目な修正例3
    Using stm As New MemoryStream(File.ReadAllBytes(bmpFile))
     PictureBox1.Image = Image.FromStream(stm)
    End Using
    PictureBox1.Image.Save(bmpFile, System.Drawing.Imaging.ImageFormat.Bmp)



    追記:こういう手もあるかな。

    Using img = Image.FromFile(pngFile)
     PictureBox1.Image = New Bitmap(img)
    End Using
    PictureBox1.Image.Save(pngFile, System.Drawing.Imaging.ImageFormat.Bmp)

    上記は、 No8405 のスレッドの "中 博俊" さん( No8447 )の案です。
    >>> New Bitmap(bmp)
    >>> で、新しいBitmapにコピーされますよ。
    >>>
    >>> ただし全てがコピーされるわけじゃなくってDPIが保持されないとか、現在のページだけ(マルチページな画像の場合)とかやや違いはありますが。
違反を報告
引用返信
■35340 / ResNo.11)  Re[11]: 複数のPictureBox画像を複数のファイルへ保存したい
□投稿者/ ま〜 一般人(46回)-(2023/01/20(Fri) 12:55:32)
  • アイコン沢山のアドバイスありがとうございます
    またまた、勉強になりました。

    少しハマりながらもなんとか目的の事が出来ました。

    重ねてありがとうございます

    クローズします。

解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-9] [10-11]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35314 / 親記事)  テキストボックスのValidatingイベントよりも先に発生するボタン発生イベントは何でしょう?
□投稿者/ saku 一般人(3回)-(2023/01/04(Wed) 13:18:24)
  • アイコン環境/言語:[C#] 
    分類:[.NET] 

    こんにちわ。前回は大変お世話になりました。
    また、一つ質問というか疑問がでてきました。

    フォーム上に、テキストボックスを一つあり、ボタンが一つあります。

    テキストボックスで入力後、ボタンを押すのですが、
    テキストボックスのValidatingイベントよりも先に発生するボタンのイベントって
    あるんでしょうか? (少し試してみたのですが、見つかりませんでした。)

    今作成しているものに必要になるかもしれない(必要ないかもしれない)ので、知識として持っておきたいため、お聞きしました。

    あいまいな質問で申し訳ありません。もし、良ければ教えてください。
    よろしくお願いいたします。

違反を報告
引用返信

▽[全レス2件(ResNo.1-2 表示)]
■35315 / ResNo.1)  Re[1]: テキストボックスのValidatingイベントよりも先に発生するボタン発生イベントは何でしょう?
□投稿者/ Azulean 大御所(536回)-(2023/01/04(Wed) 14:26:41)
  • アイコンNo35314に返信(sakuさんの記事)
    > テキストボックスで入力後、ボタンを押すのですが、
    > テキストボックスのValidatingイベントよりも先に発生するボタンのイベントって
    > あるんでしょうか? (少し試してみたのですが、見つかりませんでした。)


    ないはずです。
    Validating はフォーカスを失うときに発生します。

    1. ボタンを押そうとする
    2. テキストボックスからフォーカスが外れる
    3. Validating/Validated イベント
    4. ボタンがフォーカスを得る
    5. ボタンのクリックイベントが起きる

    こういう流れとなりますので、ボタンクリックしたときだけ Validating の挙動を変えたいみたいなことはできません。


    > 今作成しているものに必要になるかもしれない(必要ないかもしれない)ので、知識として持っておきたいため、お聞きしました。

    必要となるかもしれないのであれば、Validating で検証するという設計・実装を辞めた方が良いと思います。

    Validating は一見、良い考えのように思えるかもしれませんが、「キャンセルするときにもチェックされて手間に感じる」などの弊害もあります。
    このため、OK ボタンなど、適切なタイミングでチェックするように実装することを考えた方が良いでしょう。
違反を報告
引用返信
■35336 / ResNo.2)  Re[2]: テキストボックスのValidatingイベントよりも先に発生するボタン発生イベントは何でしょう?
□投稿者/ saku 一般人(9回)-(2023/01/17(Tue) 13:32:02)
  • アイコンすいません。解決済にするのを失念していました。

    ご返答遅れて申し訳ございません。
    情報ありがとうございました。 管理者の方と仕様変更を含めてお話することにしました。感謝します。

解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-2]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35308 / 親記事)  継承元フォームで各フォームのボタン動作を検知したい
□投稿者/ saku 一般人(1回)-(2022/12/30(Fri) 08:33:39)
  • アイコン環境/言語:[C#] 
    分類:[.NET] 

    おはようございます。
    皆さまのお知恵を拝借できないでしょうか。

    基本となるフォーム(ファンクション、デザインの統一など)を作成して
    そのフォームを継承して各機能画面を作成しているのですが、

    継承元フォームの方で、キーボード入力を検知できるように(KeyPreview=True,KeyDownイベントなど)、
    マウスでボタンにフォーカスがあたる(またはクリック)した事を検知できるような方法って何か考えられないでしょうか?

    継承元フォームの方で処理を共通化することになり、各機能画面のボタンの検知が必要になったためです。

    何かしらヒントだけでも頂けると有難いです。

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

違反を報告
引用返信

▽[全レス3件(ResNo.1-3 表示)]
■35309 / ResNo.1)  Re[1]: 継承元フォームで各フォームのボタン動作を検知したい
□投稿者/ 魔界の仮面弁士 大御所(1509回)-(2022/12/30(Fri) 10:19:06)
  • アイコンNo35308に返信(sakuさんの記事)
    > マウスでボタンにフォーカスがあたる(またはクリック)した事を検知
    マウス操作に限定した検知ということでしょうか。
    それともマウス以外の操作によるものも検出したいのでしょうか?

    たとえば Windows Touch 操作や、スタイラスによるタップも
    マウス操作によるクリックと同種に扱うという事で良いでしょうか。

    フォーカス移動にはマウス操作だけでなく、Tab / Shift+Tab 移動もあります。
    プログラムから Focus メソッドや SelectNextControl メソッド等によって
    フォーカスが移り変わることもあります。
    https://dobon.net/vb/dotnet/control/selectnextcontrol.html

    Click イベントの発火には、Alt + ニーモニックキー によるショートカット、
    フォーカス取得時の Space キーでの操作もあります。Form の
    AcceptButton / CancelButton によるショートカット操作もありますし、
    プログラムから PerformClick メソッドで呼ばれることもありますね。


    別にマウス操作に限る必要は無いのなら、継承フォーム側で OnControlAdded を
    オーバーライドして Button の追加を追跡しておき、そのボタンに対して
    GotFocus/Enter/MouseDown/Click イベントを追跡するのが良いと思います。

    その場合 Panel などの入れ子構造も再帰的にとらえる必要があるでしょう。
    状況によっては、ControlRemoved イベント/ OnControlRemoved メソッドでの
    解除処理も加えた方が良いかも知れません。


    ボタン操作と言えば、非アクティブなフォームのボタンがクリックされた場合
     ・フォームおよびそのボタンがアクティブになるだけ
     ・フォームとボタンがアクティブになり、Click イベントまで発動
    のどちらが好ましいか(Click Through の有無)という話があり、その切替を
    WndProc をオーバーライドすることで制御することがあります。
    https://learn.microsoft.com/en-us/archive/blogs/rickbrew/how-to-enable-click-through-for-net-2-0-toolstrip-and-menustrip

    「イベント」を処理する代わりに、こうした「Windows Message」を処理することで
    検出できるケースもあります。
違反を報告
引用返信
■35310 / ResNo.2)  Re[2]: 継承元フォームで各フォームのボタン動作を検知したい
□投稿者/ saku 一般人(2回)-(2022/12/30(Fri) 12:13:32)
  • アイコン詳しい説明、考慮すべき点に参考すべき情報、
    大変勉強になりました。
    今回はキー入力まわりの対応は完了しているので、マウスでのクリックに対する継承フォーム側での OnControlAdded、Windows Messageを念頭に調べてみます。

    もう感謝しかありません。
    ありがとうございました。
解決み!
違反を報告
引用返信
■35312 / ResNo.3)  Re[2]: 継承元フォームで各フォームのボタン動作を検知したい
□投稿者/ 魔界の仮面弁士 大御所(1511回)-(2022/12/30(Fri) 15:10:57)
  • アイコン
    解決済みチェックはそのままにしておきます。
    
    
    ■No35309に追記(魔界の仮面弁士の記事)
    > 別にマウス操作に限る必要は無いのなら、継承フォーム側で OnControlAdded を
    > オーバーライドして Button の追加を追跡しておき、そのボタンに対して
    > GotFocus/Enter/MouseDown/Click イベントを追跡するのが良いと思います。
    
    Button の Click イベントと Enter イベントを継承元フォームで捉えて
    独自の ControlClick / ControlEnter イベントとして発生させてみました。
    
    イベント引数 e.Control から、対象の Button オブジェクトを得られます。
    
    private void Form1_ControlClick(object sender, ControlEventArgs e)
    {
        listBox1.Items.Insert(0, $"{DateTime.Now:HH:mm:ss.ffff}/Click: {e.Control.Text}");
    }
    private void Form1_ControlEnter(object sender, ControlEventArgs e)
    {
        listBox1.Items.Insert(0, $"{DateTime.Now:HH:mm:ss.ffff}/Enter: {e.Control.Text}");
    }
    
    
    ベースクラスの実装はこんな感じ。
    
    
    // ---> SakuFormBase.cs --->
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Forms;
    using System.Collections;
    
    [DefaultEvent(nameof(SakuFormBase.ControlClick))]
    public class SakuFormBase : Form
    {
        // 実際には InitializeComponent(); の呼び出し等も記述
        public SakuFormBase() { }
    
        #region 公開イベント
        // ControlClick イベントという名に反して、Button にしか反応させていなかったりする
        [Category("Action"), Description("フォーム上の Button がクリックされた時に発生します。")]
        public event ControlEventHandler ControlClick;
        [Category("Focus"), Description("フォーム上の Button がアクティブになった時に発生します。")]
        public event ControlEventHandler ControlEnter;
        /// <summary><see cref="ControlClick"/> イベントを発生させます。</summary>
        protected virtual void OnControlClick(ControlEventArgs e) => ControlClick?.Invoke(this, e);
        /// <summary><see cref="ControlEnter"/> イベントを発生させます。</summary>
        protected virtual void OnControlEnter(ControlEventArgs e) => ControlEnter?.Invoke(this, e);
        #endregion
    
        #region 内部処理
        protected override void OnControlAdded(ControlEventArgs e)
        {
            base.OnControlAdded(e);
            // 子コントロールが追加されたら、Click/Enter イベントを捉える
            AttachEvents(e.Control);
        }
        private void AttachEvents(Control control)
        {
            if (control is Button button)
            {
                // Button が追加された時はイベントを追跡
                if (subscribes.Add(control))
                {
                    var a = new ControlEventArgs(control);
                    button.Click += (sender, e) => OnControlClick(a);
                    button.Enter += (sender, e) => OnControlEnter(a);
                }
            }
            else
            {
                // Button で無ければ、さらにその配下のコントロールに対して再帰的に追跡
                if (subscribes.Add(control))
                {
                    control.ControlAdded += (sender, e) => AttachEvents(control);
                }
                foreach (var c in control.GetControls<Control>())
                {
                    AttachEvents(c);
                }
            }
        }
        // イベントを追跡済みかどうかを管理
        private HashSet<Control> subscribes = new HashSet<Control>();
        #endregion
    }
    internal static class ControlExtensions
    {
        /// <summary>
        /// 指定した型の子孫コントロールを列挙する
        /// </summary>
        public static IEnumerable<T> GetControls<T>(this Control control) where T : Control
        {
            var controls = control.Controls.OfType<Control>();
            return controls.OfType<T>().Concat(controls.SelectMany(c => GetControls<T>(c)));
        }
    }
    // <--- SakuFormBase.cs ---
    
    
    ControlAdded イベント(OnControlAdded メソッド)を用いているのは、
    Button の追加が実行時に動的に行われた場合に備えるためのものです。
    (今回、ControlRemoved イベントの追跡は省略しています)
    
    デザイン時の画面構成のままで、ボタン数の増減が無いような場合は、
    Load 完了後に全 Button を列挙して捉えるだけでも十分かと思います。

解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-3]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35301 / 親記事)  Windowsエクスプローラからのドラッグ&ドロップ
□投稿者/ よっし〜 一般人(15回)-(2022/12/24(Sat) 08:53:12)
  • アイコン環境/言語:[VB.NET] 
    分類:[.NET] 

    現在Windowsエクスプローラからファイルをドラッグ&ドロップして、ドロップされたファイルを処理するプログラムを作成しております。

    http://dobon.net/vb/dotnet/control/droppedfile.htmlを参考にさせて頂き、あくまでも例ですが

    Private Sub ListBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragDrop
    Dim fileName As String() = CType(e.Data.GetData(DataFormats.FileDrop, False), String())
    For Each FL As String In fileName
    <FLファイルに対しての重い処理>
    Next
    End Sub
    としております。
    もちろん作成しているアプリは重い処理なので、応答無し的な状態にはなりますが、Windowsエクスプローラの方もドラッグ中(カーソルに+が付いた)のままとなってしまい、操作できません。
    アプリはともかく、Windowsエクスプローラを処理から開放する方法はありますでしょうか??

    以上、宜しくお教えくださいませ。

違反を報告
引用返信

▽[全レス2件(ResNo.1-2 表示)]
■35302 / ResNo.1)  Re[1]: Windowsエクスプローラからのドラッグ&ドロップ
□投稿者/ 魔界の仮面弁士 大御所(1507回)-(2022/12/24(Sat) 11:05:56)
  • アイコンNo35301に返信(よっし〜さんの記事)
    > アプリはともかく、Windowsエクスプローラを処理から開放する方法はありますでしょうか??

    Dim fileName As String() に受け取るだけならば、
    そんなに時間はかからないですよね?

    であれば、UI スレッドはファイルの一覧を受け取るだけにして、
    その後の処理はワーカースレッドに任せてしまえば良さそうです。
    .NET バージョンによって選択肢が変わってきますが、
    たとえば Task とか BackgroundWorker とか Thread とか…。

    ただしその場合、別スレッド操作になるので
    > <FLファイルに対しての重い処理>
    の部分では、UI 部品(TextBox とか ListBox とか Label とか)の
    読み書きは行えなくなります。
違反を報告
引用返信
■35304 / ResNo.2)  Re[2]: Windowsエクスプローラからのドラッグ&ドロップ
□投稿者/ よっし〜 一般人(16回)-(2022/12/26(Mon) 08:58:55)
  • アイコン魔界の仮面弁士さん、早速のご教示、有り難うございます。

    > であれば、UI スレッドはファイルの一覧を受け取るだけにして、
    > その後の処理はワーカースレッドに任せてしまえば良さそうです。
    > .NET バージョンによって選択肢が変わってきますが、
    > たとえば Task とか BackgroundWorker とか Thread とか…。

    BackgroundWorker使用し、フォーム等を処理から開放するのは知っておりましたが、
    Windows別アプリ(別スレッド)も開放出来るのですね。
    一度重い処理部分をBackgroundWorkerで処理する様に改造してみます。

    どうも、有り難うございました。


解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-2]



■記事リスト / ▲上のスレッド
■35297 / 親記事)  ラジオボタンの一括設定
□投稿者/ ま〜 一般人(34回)-(2022/12/23(Fri) 18:39:54)
  • アイコン環境/言語:[windows10 VS2022] 
    分類:[.NET] 

    こんにちわ、テキストファイルにラジオボタンの内容を保存して復元しようとしています

    Dim text0() As TextBox = {TextBox1, TextBox2, TextBox3}
    と同じ様に

    Dim Radio0() As RadioButton = {RadioButton1, RadioButton2, RadioButton3}
    で考えたのですが構文エラーで赤い波線が入ってます。

    何か良い方法はないでしょうか?

違反を報告
引用返信

▽[全レス7件(ResNo.3-7 表示)]
■35300 / ResNo.3)  Re[3]: ラジオボタンの一括設定
□投稿者/ 魔界の仮面弁士 大御所(1506回)-(2022/12/23(Fri) 22:45:15)
  • アイコンNo35299に返信(ま〜さんの記事)
    > エラーの内容は
    > https://learn.microsoft.com/en-us/dotnet/visual-basic/misc/bc30311?f1url=%3FappId%3Droslyn%26k%3Dk(BC30311)
    > です。

    いや、その <Type1> と <Type2> が何であったのかが重要なのですけれど?
違反を報告
引用返信
■35303 / ResNo.4)  Re[4]: ラジオボタンの一括設定
□投稿者/ ま〜 一般人(36回)-(2022/12/26(Mon) 01:23:24)
  • アイコンお世話になります。

    > いや、その <Type1> と <Type2> が何であったのかが重要なのですけれど?

    貼り付けました。

    宜しくお願いします
619×28 => 250×11
イメージ
1671985404.jpg
/13KB
違反を報告
引用返信
■35305 / ResNo.5)  Re[5]: ラジオボタンの一括設定
□投稿者/ KOZ 一般人(16回)-(2022/12/26(Mon) 09:51:46)
  • アイコン
    No35303に返信(ま〜さんの記事)
    > 貼り付けました。
    
    エラーを選択して右クリックすると内容をコピーできます。
    
    重大度レベル	コード	説明	プロジェクト	ファイル	行	抑制状態
    エラー	BC30311	型 'RadioButton' の値を 'VisualStyleElement.Button.RadioButton' に変換できません。	WindowsApp1	D:\TEST\WindowsApp1\WindowsApp1\Form1.vb	5	アクティブ
    
    こんな感じ。
    
    Imports System.Windows.Forms.VisualStyles.VisualStyleElement.Button
    
    が書いてあるとこのエラーになりますが、使っているんでしょうか?

違反を報告
引用返信
■35306 / ResNo.6)  Re[5]: ラジオボタンの一括設定
□投稿者/ 魔界の仮面弁士 大御所(1508回)-(2022/12/26(Mon) 09:53:31)
  • アイコンNo35303に返信(ま〜さんの記事)
    >>いや、その <Type1> と <Type2> が何であったのかが重要なのですけれど?
    > 貼り付けました。

    画像でも良いですが、エラー一覧の内容は
    右クリック操作もしくは Ctrl+C を使って
    テキストとしてコピーできますよ。


    エラー BC30311 型 'RadioButton' の値を 'VisualStyleElement.Button.RadioButton' に変換できません。

    …というエラーメッセージは、代入式の右辺が `RadioButton` 型であるの対して、
    代入先の左辺の RadioButton 型が `VisualStyleElement.Button.RadioButton` 型という、
    「型名はどちらも RadioButton 型だが、所属する名前空間の異なる別物」への操作だと思われています。



    今回の場合、プロジェクト作成時のテンプレートとして、おそらく
     ★Windows フォーム アプリケーション (.NET Framework)
     ★Windows フォーム アプリ
    のいずれかを選択されている状況なのでしょう。

    そして現在は、Form1.vb ファイルの冒頭に、普段は記述されていないはずの
     Imports System.Windows.Forms.VisualStyles.VisualStyleElement.Button
    というコードが追加されている状況であると想像できます。もしそうなら、
     Dim Radio0() As RadioButton = {RadioButton1, RadioButton2, RadioButton3}
    という代入式左辺の As RadioButton とは
     As System.Windows.Forms.VisualStyles.VisualStyleElement.Button.RadioButton
    の意味になっています。一方、代入式右辺にある RadioButotn1〜3 は
     As System.Windows.Forms.RadioButton
    に相当するデータ型を意味するため、型の不一致でコンパイルエラーとなります。


    解決策としては、こんな感じ。

    (案1) 冒頭の「Imports System.Windows.Forms.VisualStyles.VisualStyleElement.Button」宣言を取り除く
    (案2) 変数宣言時に、クラス名だけでなく名前空間も明示するようにする
     Dim Radio1() As RadioButton = {…}
    →Dim Radio1() As Global.System.Windows.Forms.RadioButton = {…}


    > TEXTの方は問題ないです
    もしも「Imports System.Windows.Forms.VisualStyles.VisualStyleElement」という宣言が
    追加されていたら、As TextBox も同様の競合問題が発生していたことでしょう。


    なお、今回は状況的に Windows Forms での事象だったのでしょうけれども
    その他プロジェクトでも同種の問題は起こりえます。

    "RadioButton" ひとつとっても、これだけの種類があるので…。

    ・System.Windows.Forms.RadioButton クラス (System.Windows.Forms.dll)
    ・System.Windows.Forms.VisualStyles.VisualStyleElement.Button.RadioButton クラス (System.Windows.Forms.dll)
    ・System.Windows.Controls.RadioButton クラス (PresentationFramework.dll)
    ・System.Web.UI.WebControls.RadioButton クラス (System.Web.dll)
    ・System.Windows.Automation.ControlType.RadioButton フィールド (UIAutomationTypes.dll)
    ・System.Windows.Automation.Peers.AutomationControlType.RadioButton 列挙値 (PresentationFramework.dll)
    ・Microsoft.Windows.Themes.ClassicBorderStyle.RadioButton 列挙値 (PresentationFramework.Classic.dll)
違反を報告
引用返信
■35307 / ResNo.7)  Re[6]: ラジオボタンの一括設定
□投稿者/ ま〜 一般人(37回)-(2022/12/26(Mon) 16:11:48)
  • アイコンいつも適切なアドバイスお二人に感謝です
    ありがとうございます

    まさにこれでした。

    今までネット上のサンプルをコピペで試してる時、ソースが大きくなるだけだと思って深く考えずにインポートしたままにしてましたが今回の件で勉強になりました。

    再度ありがとうございます

    クローズしておきます


解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-7]






Mode/  Pass/


- Child Tree -