CSVのデータを元に、複数のラベルコントロールやラインコントロールで
(タイムラインのような表のため)
フォームにいろいろなデータを表のように書き込んで、印刷/画像として
出力をするようなプログラムを作っているのですが、
どのようにすれば画像として保存できるのかよくわかりません。
MDIフォームの子のフォーム丸ごとを画像として出力するというような
方法でもいいので、教えてください。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

[PrintScreen]ボタンは画面全体のスナップショット


[Alt]+[PrintScreen]はアクティブ画面などのスナップショットです。
子フォームだけのスナップショットは、キー操作だけでは標準では無理ですね。。。


サンプルです。

手順としては
1.子フォームとなっているフォーム1が、デスクトップ上のどの位置に存在するか座標を得る
2.画像作成用のピクチャボックスをその領域座標とおなじ大きさになるように、大きさをセットする
3.デスクトップ領域のフォーム1の座標部分を、ピクチャボックスに描画
4.保存

というのが大きな流れです。

必要なもの
MDIForm1
Form1(デザイン時にMDIChild=True)
├コマンドボタン
└ピクチャボックス


-----Form1ここから-----
Option Explicit


Private Type RECT
  Left As Long
  Top As Long
  Right As Long
  Bottom As Long
End Type
Private Type POINTAPI
  x As Long
  y As Long
End Type

Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long

Private Sub Command1_Click()
  Dim recWork As RECT
  Dim lngL As Long, lngT As Long, lngW As Long, lngH As Long
  Dim lngDeskTopWnd  As Long 'デスクトップハンドル
  Dim lngDescTooDC  As Long 'デスクトップデバイスコンテキストハンドル
  
  With Me
    'フォームの座標を得る
    Call GetWindowRect(.hwnd, recWork)
    
    '左位置、上位置。幅、高さを得る
    With recWork
      lngL = .Left: lngT = .Top: lngW = .Right - lngL: lngH = .Bottom - lngT
    End With
    
    'ピクチャボックスのサイズ設定(左位置=0:上位置=0幅=lngW:高さ=lngH)
    Call MoveWindow(.Picture1.hwnd, 0, 0, lngW, lngH, 1)
    
    'デスクトップハンドルを得る
    lngDeskTopWnd = GetDesktopWindow
    'デスクトップのデバイスコンテキストハンドルを得る
    lngDescTooDC = GetDC(lngDeskTopWnd)
    
    'デスクトップ上のlngL:lngT:lngW:lngHの範囲を、ピクチャボックスに描画
    'lngL:lngT:lngW:lngHにはフォーム1が存在しているので、実質フォーム1を描画することになる
    Call StretchBlt(.Picture1.hdc, 0, 0, lngW, lngH, lngDescTooDC, lngL, lngT, lngW, lngH, vbSrcCopy)
    
    'デバイスコンテキストをリリースする
    Call ReleaseDC(lngDeskTopWnd, lngDescTooDC)
    
    
    '画像を保存
    Call SavePicture(.Picture1.Image, "c:\test.bmp")
  End With
End Sub

Private Sub Form_Load()
  With Me
    With .Picture1
      .Appearance = 1   'フラット
      .BorderStyle = 0  '枠線なし
      .AutoRedraw = True '自動再描画
      .Visible = False
    End With
  End With
End Sub
-----Form1ここまで-----


-----MDIForm1ここから-----
Option Explicit

Private Sub MDIForm_Load()
  Form1.Show
End Sub
-----MDIForm1ここまで-----

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=185224
    • good
    • 0
この回答へのお礼

ちょっとお礼が遅くなりましたが、ありがとうございます。
APIを扱うのは初めてなので、自分の思い通りに扱えるようにするには
時間がかかりそうですが、今月中になんとか出来ればいいので、
専門書を読んで、一つづつ命令の意味を理解しながらやっていきたいと思います。

お礼日時:2002/01/22 19:19

センドキーでプリントスクリーンは効かないんで困るんですよねぇ。

仕様でしょうか。
印刷は Me.PrintForm で何とかなるにしてもファイル保存はたいへんですね。
もし、他社ツールOKであるならば明熊さん(下記URL)のtransG32なんかを利用してみてはどうでしょう?直接ウィンドウハンドル送ってやればうまくいくと思いますよ。

他にはAPIをたたいてあげるしかないとおもいます。

参考URL:http://www.akikuma.cx/Download.htm
    • good
    • 0

[alt]+[print screen]でウィンドウの画像コピーして、ワード、エクセルや


ペイントに貼り付けではだめですか?
    • good
    • 0

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

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

QMDI:親フォームと子フォームを別EXEで実装するには

MDIでアプリケーションを作成したいと思っています。
その時に子フォームを親フォームとは別EXEで作りたいと思っています。
例えば
親フォームのボタンを押すと、子フォームEXEが起動し、親フォーム内に表示される。
このようなことは出来ますか?
出来るのでしたら、どうしたらよろしいでしょうか。
教えてください。

Aベストアンサー

手順的には
http://okweb.jp/kotaeru.php3?q=102408の#2
だと思います。
キーワードは「API関数:SetParent」
このAPIで、別EXEでもなんでも、内部に取り込むだけはできます。

しかしMDIを実現するためには、かなり制御を組み入れないといけません。
参考URLでも述べているように、最大領域だけならず終了時処理など、それ以外にも想像しえない本来のMDIとして用意されている標準制御を、実現しなければなりません。

かな~り手間だと思います。

QMDI親フォームで子フォーム開放を知る

はじめまして。VB.NET2005でプログラミングをしている初心者です。
MDIフォームのAPを作成しています。
MDI親フォーム1つと子フォームが2つあるとします。

親フォームから子フォーム2つをShowします。
子フォーム1を閉じたときに、親フォーム内で子フォーム1が閉じられた事を知るすべは無いのでしょうか。
親フォーム内で起こるイベントでどの子フォームが閉じられたかを得たいと思っています。

どなたか分かる方いらっしゃいましたらご教授ください。
宜しくお願い致します。

Aベストアンサー

#1さんと同じw

ただ「Dispased」だとどちらが終了したのか分からないんじゃ…
で、すなおに「Form_Closing」か「Form_Closed」がいいのでは?

子フォームを開く前に下記追加
AddHandler ChildForm.FormClosing, AddressOf ChildForm_FormClosing

親フォームのどこかに下記追加
Private Sub ChildForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
  Dim frm As Form = DirectCast(sender, System.Windows.Forms.Form)
  MessageBox.Show(String.Format("formname=[{0}] frmtext=[{1}]", frm.Name, frm.Text))
End Sub

QVB2010でMDI親フォームから子フォームを表示

VB2010でソフトを作っております。
MDI親フォームから子フォームを表示させたいのですが…。
過去に少しだけVB6を使っていたことがありますが、クラスという概念に苦労しております
インスタンスや初期化といったところをうまく扱えばとは思うのですが、よろしくご指導お願いいたします。

1.MDI親フォーム(Form1)のボタンを押し、子フォーム(Form2)を表示させる
2.子フォームが表示されていなかったら表示させる
3.子フォームが表示されていたら何もしない

これだけの事ですがずいぶん悩んでおります。
全コードがこれです。

Public Class Form1
Private f2 As New Form2

Private Sub Form1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.IsMdiContainer = True
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim fChild As Form() = Me.MdiChildren
For Each f As Form In fChild
If f.Text = "Form2" Then
Exit Sub
End If
Next


f2 = New Form2
f2.MdiParent = Me
f2.Show()
f2.Activate()

End Sub


Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

If f2 Is Nothing OrElse f2.IsDisposed Then
f2 = New Form2
f2.MdiParent = Me
End If
f2.Show()
f2.Activate()

End Sub

End Class


ボタン1でもボタン2でも、期待する動作はするのですが、

ボタン1ではアクティブになっているフォームの名前を力技で取得している気がして…
ボタン2では子フォーム(Form2)をすでに表示している状態でもさらにShowをしているのが気に入らなくて…

もっとスマートな方法がありましたら、ご指導お願いします。

VB2010でソフトを作っております。
MDI親フォームから子フォームを表示させたいのですが…。
過去に少しだけVB6を使っていたことがありますが、クラスという概念に苦労しております
インスタンスや初期化といったところをうまく扱えばとは思うのですが、よろしくご指導お願いいたします。

1.MDI親フォーム(Form1)のボタンを押し、子フォーム(Form2)を表示させる
2.子フォームが表示されていなかったら表示させる
3.子フォームが表示されていたら何もしない

これだけの事ですがずいぶん悩んでおります。
全コード...続きを読む

Aベストアンサー

Private f2 As New Form2

Private f2 As Form2
にして

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

If f2 Is Nothing OrElse f2.IsDisposed Then
f2 = New Form2
f2.MdiParent = Me
f2.Show()
End If
f2.Activate()

End Sub

としてみては?

QMDIの子フォームでフォーカスアウトを制御したい

MDIの子フォームでフォーカスアウトを制御したい

VB2005で開発を行っています。

・MDIの子フォームA、Bが存在します。
・子フォームA、Bともに、表示されています。
・子フォームAにはテキストコントロールAA、ABの2つが存在します。
・テキストコントロールAAのLostFocus()に、テキストコントロールAA.Focus()が
 記されています。

この状態で、子フォームAのテキストコントロールAAからABへフォーカスが移った時、
コントロールAAのLostFocus()で制御するのはうまくいきます。

が、子フォームAのテキストコントロールAAから子フォームBへフォーカスが移った時、
コントロールAAのLostFocus()が動作しますが、無限ループっぽい動きに陥ったり、
子フォームAにフォーカスが設定されません。

子フォームを最小化させたり、全然関係のないアプリケーションやデスクトップに
フォーカスを遷移したあとにフォーカスを戻してみても同じような現象になります。

イメージとしては、フォーカスアウトでエラーになったんだから、フォーカスを移し
たくないです。

Private Sub ControlAA_LostFocus(ByVal sender As System.Object, ByVal e As System.EventArgs)
 If "".Equals(ControlAA.Text) Then
  MessageBox.Show("hoge")
  ControlAA.Focus()
  Return
 End If
End Sub

フォーカスアウト時に項目チェックなどをやる関係で、どうしてもLostFocus()上で
処理をやらなければならないと思われるのですが、フォーカスアウトされた時のオペ
レーションの違いに限らず上手く制御させる方法はありませんでしょうか?

調べてはみましたが、MDIの概念でそもそもそういうことするなというような事らしいですが、
フォーカスアウト時に検索処理が走るというような仕様の為、どうしても解決させたいです。

MDIの子フォームでフォーカスアウトを制御したい

VB2005で開発を行っています。

・MDIの子フォームA、Bが存在します。
・子フォームA、Bともに、表示されています。
・子フォームAにはテキストコントロールAA、ABの2つが存在します。
・テキストコントロールAAのLostFocus()に、テキストコントロールAA.Focus()が
 記されています。

この状態で、子フォームAのテキストコントロールAAからABへフォーカスが移った時、
コントロールAAのLostFocus()で制御するのはうまくいきます。

が、子フォームAのテキスト...続きを読む

Aベストアンサー

> フォーカスアウト時に項目チェックなどをやる関係で、どうしてもLostFocus()上で
> 処理をやらなければならないと思われるのですが、フォーカスアウトされた時のオペ
> レーションの違いに限らず上手く制御させる方法はありませんでしょうか?

Validatingイベントを使えばいいってことでは。

QVB.NET MDI親フォームのスクロールバー制御

開発環境:Windows XP、VB.NET 2005

MDI親フォームに複数のMDI子フォームを貼り付けるプログラムを作っています。
MDI子フォームを重ならないように配置させているのですが、MDI親フォームの表示領域を超えた場合に自動的にスクロールバーが現れます。
この時に、マウスのホイールの上下の動きにあわて、MDI親フォームのスクロールバーを制御して画面を上下させたいのですが方法が分かりません。

どなたかご享受ください。

Aベストアンサー

やるとすると MDIの親フォームのクライアントウィンドウに対して
WM_VSCROLL(または WM_HSCROLL)メッセージを投げてやる必要があるようです

MDIフォームクラスに
dim client as MdiClient
Declare Auto Function SendMessage Lib "User32" _
  (ByVal hWnd As IntPtr, ByVal uMsg As UInt32, _
   ByVal wParam As Int32, ByVal lParam As Int32) As Int32
const WM_VSCROLL as UInt32 = &H115
const WM_HSCROLL as UInt32 = &H114
を宣言します

Loadイベントで
for each ctl as Control in Controls
  if typeof ctl is MdiClient then
    client = ctl
    exit for
  end if
next

MouseWheelイベントで
dim wp as Int32 = 0
if e.delta < 0 then
  wp = 1
end if
SendMessage( client.Handle, WM_VSCROLL, wp, 0 )
といった具合でいいようですよ

やるとすると MDIの親フォームのクライアントウィンドウに対して
WM_VSCROLL(または WM_HSCROLL)メッセージを投げてやる必要があるようです

MDIフォームクラスに
dim client as MdiClient
Declare Auto Function SendMessage Lib "User32" _
  (ByVal hWnd As IntPtr, ByVal uMsg As UInt32, _
   ByVal wParam As Int32, ByVal lParam As Int32) As Int32
const WM_VSCROLL as UInt32 = &H115
const WM_HSCROLL as UInt32 = &H114
を宣言します

Loadイベントで
for each ctl as Control in Co...続きを読む


このカテゴリの人気Q&Aランキング

おすすめ情報