OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

ピクチャーボックスのサイズを変えたら表示されてるのまでいっしょに大きさを変えたい

  • 暇なときにでも
  • 質問No.168025
  • 閲覧数565
  • ありがとう数6
  • 気になる数0
  • 回答数6
  • コメント数0

お礼率 47% (159/337)

タイトルにあるようにピクチャーボックスの
サイズを変えたら表示されてるのまでいっしょに大きさを変えたい
のですがそうしたらいいかわかりません誰か教えてください
通報する
  • 回答数6
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

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

  • 回答No.3
レベル13

ベストアンサー率 46% (643/1383)

>作ってるプログラムに会うように変更を加えたいので
詳しく解説も入れていただけるとありがたいです

了解しました。
まず概要ですが、描画用のピクチャボックスと表示用のピクチャボックスを作り、ピクチャボックスに対する描画などは描画用ピクチャボックスに行い、適当なタイミングで表示用ピクチャボックスに拡大縮小しつつ転送しようって言うのが趣旨です。「適当なタイミング」については後述します。

この操作のキモである「拡大縮小しつつ転送」を実現する方法には、#1でTAGOSAKU7さんが書いておられるPaintPictureステートメントを使う方法と、私が採用したStretchBLTを使う方法とが考えられます。

VBの標準ステートメントであるPaintPictureを使っても良かったんですが、個人的な趣味と、QNo.168025での回答との整合性も考えまして、Windowsの機能であるStretchBLTを使うことにしました。


さて、先ほど記述した「適当なタイミング」ですが、
今回の場合ですと、「A:描画用ピクチャボックスに描画等の処理を加えた直後」「B:表示用ピクチャボックスのサイズ変更を行った直後」「C:Windowsから再描画を要求されたとき」
の3つを押さえておけばいいです。

具体的には、
A:
Picture2.Psetなどを使って一通りの描画プログラムを記述した後、その次の行に
Call StretchBlt(Me.Picture1.hdc,…
と書く。

B:
Picture1.Width = 640
ってな感じで表示用のピクチャボックスのサイズを変更した次の行に、
Call StretchBlt(Me.Picture1.hdc,…
って書く。

C:
表示用のピクチャボックスのAutoRedrawプロパティをTrueに設定している場合には、特に何もしなくても良い。
(VBが勝手に再描画してくれる。)


以下、ソースコードの解説です。
(General)(Declarations) のDeclare~で、VBからStretchBLTを呼び出す為に必要な宣言を書いています。
Decrare~を使うと、外部のDLLとかに含まれる機能を呼び出すことが出来るようになります。

今回の「Declare Function StretchBlt…」については、VB付属のWin32API.txtというファイルからの(ほぼ)丸写しですね。代表的なWindowsの機能は「Win32API.TXT」に記述してありますし、VBのアドイン機能である「VB API Viewer」を使えば、名称などから必要な宣言分を検索することが出来ます。


Form_Resize()イベントプロシージャは、ピクチャボックスの大きさを変更したときのサンプルですね。

Me.Picture1.Left = 0
Me.Picture1.Top = 0
Me.Picture1.Width = Me.Width
Me.Picture1.Height = Me.Height
で、試しに表示用ピクチャボックスの大きさを変更しています。

その次の
Call StretchBlt…
の行で、描画用ピクチャボックスから表示用ピクチャボックスに、画像を転送しています。

StretchBLTは、以下のように引数を指定します。
Call StretchBLT(複写先のオブジェクトのhDCプロパティ, 複写先のX座標, Y座標, 幅,
高さ, 複写元オブジェクトのhDCプロパティ, 複写元のX座標, Y座標, 幅, 高さ,
転送モード)
引数中のX座標、Y座標、幅、高さについては、ピクセル単位で値を指定することになっていますので、
各ピクチャボックスのScaleModeプロパティを、「3-ピクセル」に設定したわけです。

こんな感じで分かりますでしょうか。できるだけ分かりやすく書いたつもりですが、まだまだ専門用語が多いかも…
分かりにくい点とかがあれば、遠慮なくご質問ください。
お礼コメント
ryuta_mo

お礼率 47% (159/337)

わざわざ何回もありがとうございます
だいたいわかりましたがひとつだけわからないとこがあります
hDCプロパティって何ですか?
何度もすみません
投稿日時 - 2001-11-14 16:50:07
-PR-
-PR-

その他の回答 (全5件)

  • 回答No.1
レベル12

ベストアンサー率 65% (276/422)

>ピクチャーボックスの サイズを変えたら とありますが、プログラム実行中に何度もサイズ変更が発生するのですか? たぶん処理としては 1.ダミーのピクチャボックスに画像を呼び込む 2.PaintPicturで画面に表示するメインのピクチャボックスにダミーから描画(画像転送) 3.「サイズ変更が発生した時」参照 4.サイズ変更後処理関数 「サイズ変更が発生した時」として、二 ...続きを読む
>ピクチャーボックスの サイズを変えたら
とありますが、プログラム実行中に何度もサイズ変更が発生するのですか?


たぶん処理としては
1.ダミーのピクチャボックスに画像を呼び込む
2.PaintPicturで画面に表示するメインのピクチャボックスにダミーから描画(画像転送)
3.「サイズ変更が発生した時」参照
4.サイズ変更後処理関数


「サイズ変更が発生した時」として、二つの方法があります。
1.ピクチャボックスサイズの変更の命令をかけるたびに、サイズ変更後処理関数を呼ぶ
2.プロセス監視をして、ピクチャボックスサイズ変更終了を読み取り、自動的にサイズ変更後処理関数を発生させる。


共通な部分として「サイズ変更後処理関数」が必要なことです。
ダミーのピクチャボックスと現在のピクチャボックスのサイズの比を取って、PaintPictureで縮尺を反映させながらメインのピクチャボックスに描画をします。
お礼コメント
ryuta_mo

お礼率 47% (159/337)

ありがとうございます
言ってることはわかるんですけどどういうソースを書いたらいいのかよくわかりません
その辺まで詳しく教えて欲しいです
投稿日時 - 2001-11-13 19:19:18
  • 回答No.2
レベル13

ベストアンサー率 46% (643/1383)

まず、描画用のピクチャボックスと表示用のピクチャボックスを作ります。 表示用ピクチャボックスをPicture1, 描画用をPicture2 とします。 Picture1は、プロパティを以下のように設定。  Visible: True  ScaleMode: 3-ピクセル  Width,Height: 適当 Picture2は、プロパティを以下のように設定。  AutoRedr ...続きを読む
まず、描画用のピクチャボックスと表示用のピクチャボックスを作ります。

表示用ピクチャボックスをPicture1, 描画用をPicture2 とします。

Picture1は、プロパティを以下のように設定。
 Visible: True
 ScaleMode: 3-ピクセル
 Width,Height: 適当


Picture2は、プロパティを以下のように設定。
 AutoRedraw: True
 Visible: False
 ScaleMode: 3-ピクセル
 Width,Height: 表示用領域に転送する画面の大きさ

で以下のような感じでコーディングしてください。

'(General)(Declarations)

'APIの宣言
Option Explicit
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 RasterOpConstants) As Long

Private Sub Form_Resize()
  'ピクチャボックスの大きさをフォームの大きさに合わせる
  Me.Picture1.Left = 0
  Me.Picture1.Top = 0
  Me.Picture1.Width = Me.Width
  Me.Picture1.Height = Me.Height
  
  'Pikture2の内容を変形して、Picture1に転送
  Call StretchBlt(Me.Picture1.hdc, 0, 0, Me.Picture1.ScaleWidth, Me.Picture1.ScaleHeight _
    , Me.Picture2.hdc, 0, 0, Me.Picture2.ScaleWidth, Me.Picture2.ScaleHeight _
    , vbSrcCopy)
  Me.Picture1.Refresh
End Sub

不明点等がありましたら、補足にてご質問ください。
お礼コメント
ryuta_mo

お礼率 47% (159/337)

回答ありがとうございます
作ってるプログラムに会うように変更を加えたいので
詳しく解説も入れていただけるとありがたいです
投稿日時 - 2001-11-13 20:51:45
  • 回答No.4
レベル12

ベストアンサー率 65% (276/422)

最近、寝不足なので寝ちゃいました。。。 補足お願いします。 ピクチャボックスに描画する絵は。ピクチャボックス原型の縦横の比を維持するのですか?、それともピクチャボックスのサイズにぴったり合わせて、縦横の比を維持しないで表示させるのですか? 1.維持させる場合 ピクチャボックスの中央になるようにでいいですか? 2.維持させない場合 特に質問はありません。 3.共通し ...続きを読む
最近、寝不足なので寝ちゃいました。。。

補足お願いします。

ピクチャボックスに描画する絵は。ピクチャボックス原型の縦横の比を維持するのですか?、それともピクチャボックスのサイズにぴったり合わせて、縦横の比を維持しないで表示させるのですか?

1.維持させる場合
ピクチャボックスの中央になるようにでいいですか?


2.維持させない場合
特に質問はありません。


3.共通した質問で
フォームのサイズの変更に伴いピクチャボックスのサイズを変更するのですか?
それともフォームのサイズと関係なく、ピクチャボックスのサイズを変更するのですか?


それと
http://oshiete1.goo.ne.jp/kotaeru.php3?q=157508
で一度発言したのですが・・・
描画にはPaintPicture以外にBitBltやStretchBltがあります。

画像の拡大縮小を行う時はPaintPictureで行うのが一番高速な処理のようです。
今は亡き
「VisualBasic 増強作戦」←昔のVBプログラマは誰もが見てました。
ここで実証が記されてました。
補足コメント
ryuta_mo

お礼率 47% (159/337)

ピクチャーボックス自体の縦横の比が変わることはありません
フォームの大きさにあわせてピクチャーボックスのサイズを変更します
If Form2.Height > Form2.Width Then Form2.Height = Form2.Width Else: Form2.Width = Form2.Height
Picture1.Width = Form2.ScaleWidth
Picture1.Height = Form2.ScaleHeight
投稿日時 - 2001-11-14 16:37:26
  • 回答No.5
レベル12

ベストアンサー率 65% (276/422)

これはピクチャボックスの中央に表示を行うプログラムです。 使えたら使ってください。 'ダミーのピクチャボックスから、ダイアログのピクチャボックスの中央に転送 Private Sub pastPicCenter(inMainPic As PictureBox, inDmyPic As PictureBox)   Dim wkMainW As Long   Dim wkMainH ...続きを読む
これはピクチャボックスの中央に表示を行うプログラムです。

使えたら使ってください。

'ダミーのピクチャボックスから、ダイアログのピクチャボックスの中央に転送
Private Sub pastPicCenter(inMainPic As PictureBox, inDmyPic As PictureBox)
  Dim wkMainW As Long
  Dim wkMainH As Long
  Dim wkDmyW As Long
  Dim wkDmyH As Long
  
  '貼り付け先の左位置/上位置/幅/高さ
  Dim wkL As Long, wkT As Long, wkW As Long, wkH As Long
  
  Dim sngXYScaleMain As Single
  Dim sngXYScaleDmy  As Single
  
  'メインの幅/高さ
  With inMainPic
    wkMainW = .ScaleWidth
    wkMainH = .ScaleHeight
  End With
  
  'ダミーの幅/高さ
  With inDmyPic
    wkDmyW = .ScaleWidth
    wkDmyH = .ScaleHeight
  End With
 
  '横:縦 の比率を求める
  sngXYScaleMain = wkMainH / wkMainW
  sngXYScaleDmy = wkDmyH / wkDmyW
  
  '----- 縮尺からメインの幅高さに適した新たな幅高さを算出 -----
  'ダミーの絵がメインエリアより縦長
  If sngXYScaleMain < sngXYScaleDmy Then
    wkH = wkMainH
    wkW = wkH / sngXYScaleDmy
  'ダミーの絵がメインエリアより横長
  Else
    wkW = wkMainW
    wkH = wkW * sngXYScaleDmy
  End If
 
  '新たな幅高さからピクチャボックスの
  wkL = (wkMainW - wkW) \ 2
  wkT = (wkMainH - wkH) \ 2
 
  Call inMainPic.PaintPicture(inDmyPic.Picture, wkL, wkT, wkW, wkH, 0, 0, wkDmyW, wkDmyH, vbSrcCopy)
End Sub
お礼コメント
ryuta_mo

お礼率 47% (159/337)

回答ありがとうございます
これを元にいろいろやってみます
投稿日時 - 2001-11-17 23:50:57
  • 回答No.6
レベル13

ベストアンサー率 46% (643/1383)

>hDCプロパティって何ですか? これを詳しく説明しようとすると、Windowsの根幹に関わるところから始めなくてはいけなくなります(^^; えーっとですねぇ、以下のようにお考え下さい。 ○とかく描画に関わるオブジェクトには「デバイスコンテキスト(DC)」っていうものが入っている。 ○WindowsにはDCに対する描画命令や転送命令が各種装備されており、これを使えば、同じ命令でフォー ...続きを読む
>hDCプロパティって何ですか?

これを詳しく説明しようとすると、Windowsの根幹に関わるところから始めなくてはいけなくなります(^^;

えーっとですねぇ、以下のようにお考え下さい。
○とかく描画に関わるオブジェクトには「デバイスコンテキスト(DC)」っていうものが入っている。

○WindowsにはDCに対する描画命令や転送命令が各種装備されており、これを使えば、同じ命令でフォームやプリンターなどのオブジェクトに対して描画を行うことが出来る。

○hDCは、DCの「ハンドル」、つまりDCの住所みたいなもので、描画用命令にhDCを渡せば、描画用命令はこの住所を参照し、適切なデバイスコンテキストに対して描画処理を行う。

っていうような感じです。
お礼コメント
ryuta_mo

お礼率 47% (159/337)

ありがとうございます
一つ一つのオブジェクトのアドレスと言うことですね
よくわかりました
投稿日時 - 2001-11-17 23:52:26
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ