プロが教えるわが家の防犯対策術!

タイトルにあるようにピクチャーボックスの
サイズを変えたら表示されてるのまでいっしょに大きさを変えたい
のですがそうしたらいいかわかりません誰か教えてください

A 回答 (6件)

>作ってるプログラムに会うように変更を加えたいので


詳しく解説も入れていただけるとありがたいです

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

この操作のキモである「拡大縮小しつつ転送」を実現する方法には、#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-ピクセル」に設定したわけです。

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

わざわざ何回もありがとうございます
だいたいわかりましたがひとつだけわからないとこがあります
hDCプロパティって何ですか?
何度もすみません

お礼日時:2001/11/14 16:50

>hDCプロパティって何ですか?



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

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

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

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

っていうような感じです。
    • good
    • 0
この回答へのお礼

ありがとうございます
一つ一つのオブジェクトのアドレスと言うことですね
よくわかりました

お礼日時:2001/11/17 23:52

これはピクチャボックスの中央に表示を行うプログラムです。



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

'ダミーのピクチャボックスから、ダイアログのピクチャボックスの中央に転送
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
    • good
    • 0
この回答へのお礼

回答ありがとうございます
これを元にいろいろやってみます

お礼日時:2001/11/17 23:50

最近、寝不足なので寝ちゃいました。

。。

補足お願いします。

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

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


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


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


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

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

この回答への補足

ピクチャーボックス自体の縦横の比が変わることはありません
フォームの大きさにあわせてピクチャーボックスのサイズを変更します
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
    • good
    • 0

まず、描画用のピクチャボックスと表示用のピクチャボックスを作ります。



表示用ピクチャボックスを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

不明点等がありましたら、補足にてご質問ください。
    • good
    • 0
この回答へのお礼

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

お礼日時:2001/11/13 20:51

>ピクチャーボックスの サイズを変えたら


とありますが、プログラム実行中に何度もサイズ変更が発生するのですか?


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


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


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

ありがとうございます
言ってることはわかるんですけどどういうソースを書いたらいいのかよくわかりません
その辺まで詳しく教えて欲しいです

お礼日時:2001/11/13 19:19

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