C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

全過去ログを検索

<< 0 | 1 >>
■8310  Re[5]: VS2005 RegAsmでアセンブリが登録できない
□投稿者/ 渋木宏明(ひどり) -(2007/09/27(Thu) 18:18:20)
>
    >>RegAsm と署名の間には何ら特別な関連はなかったと思いますけど?
    >
    >
    > 著名の箇所に、[アセンブリを COM 参照可能にする] という項目があり、

    (クラスライブラリプロジェクトの)プロジェクト設定の「署名」ページには、それらしい設定は見当たりませんけど?

    「署名」ページではなく、「ビルド」のページに「COM 相互運用機能の登録」という設定はありますが、これは「ビルド終了時に RegAsm を実行する=ビルドされた .dll を COM コンポーネントとしてレジストリに登録する」だけのものです。つまり、ビルドを実行したマシンでしか意味を持ちません。

    それと、COM コンポーネントとして利用することだけが目的なら、GAC 登録も不要です。

    >>てか、本当に GAC への登録や RegAsm で COM コンポーネントとしての登録が必要なんですか?
    >
    > 前回思いっきりスルーされてしまったのですが、BandObjectというライブラリを使って、
    > IEにツールバーを表示させたく、RegAsmでCOM コンポーネントとしての登録が必要だと思ってます。

    そういう個人的な事情はどっかに書き添えておいてもらわないと分からんすよ。
    「それくらい投稿者のハンドルで検索してリサーチしとけ」ってことならごめんなさい、僕にはそこまでできません。
記事No.8298 のレス /過去ログ20より / 関連記事表示
削除チェック/

■19689  XMLのプレフィックスの出力につきまして
□投稿者/ ishikawa -(2008/05/27(Tue) 19:38:25)

    分類:[XML] 

    初めて質問させていただきます。
    よろしくお願い致します。

    Linqを用いて、以下のような XMLを出力しようとしております。

    <SampleXML xmlns="http://www.tempuri.org1"
    xmlns:aaa="http://www.tempuri.org2"
    bbb:ccc=" http://www.tempuri.org3" >  ←問題の箇所です(bbb:)
    (以下略)

    問題となっているのが、属性の名前空間のところです。

    XNamespace ns = "http://www.tempuri.org1";
    XName problem;
    XElement pSample = new XElement("SampleXML",
    new XAttribute("xmlns", "http://www.tempuri.org1"),
    new XAttribute(XNamespace.Xmlns + "aaa", "http://www.tempuri.org2"),
    new XAttribute(problem, "http://www.tempuri.org3")); ←問題の箇所です

    属性の名前空間は、XName で指定される必要があります。
    XName は、皆様ご存知の通り、コンストラクタを持たず、
    文字列を指定することで、通常、設定できてしまいます。

    しかし、名前空間を持つ場合、どのように記述すればよろしいでしょうか。

    new XAttribute("bbb:ccc", "http://www.tempuri.org3")

    というような記述は、当然ながら、エラーになってしまいます。
    (勝手にコロンを記入されては、おかしくなってしまいますので・・・。)
    ですが、下記のように記述すると、

    XNamespace ns = "http://www.tempuri.org1";
    XNamespace ddd;
    (中略)
    XName problem = ddd + "ccc";
    XElement pSample = new XElement("SampleXML",
    new XAttribute("xmlns", "http://www.tempuri.org1"),
    new XAttribute(XNamespace.Xmlns + "aaa", "http://www.tempuri.org2"),
    new XAttribute(problem, "http://www.tempuri.org3"));

    pSample.ToString()とした場合、

    <SampleXML xmlns="http://www.tempuri.org1"
    xmlns:aaa="http://www.tempuri.org2"
    p0:ccc=" http://www.tempuri.org3" >  ←p0

    と出力されてしまいます。
    (名前を指定していないためか、"p0"という出力になってしまいます。)

    XName はXNamespaceと自身の名称からなっているわけですが、
    XNamespaceの「呼び名」を指定する(bbb:というように)ことは可能でしょうか?
    XNamespace.Xmlnsであれば、自動的に"xmlns:"と出力してくれるのですが、
    それにあたる文字列は、どうすれば設定できますでしょうか。

    よろしければ、アドバイスをいただければと思います。
    どうか宜しくお願い致します。
親記事 /過去ログ38より / 関連記事表示
削除チェック/

■34650  Re[1]: 埋め込みリソースをコピー
□投稿者/ よねKEN -(2009/04/04(Sat) 21:11:31)
    > private void button0_Click(object sender, EventArgs e)
    > {
    > System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
    > string resourceName = asm.GetName().Name + ".hoge.wav";

    Stream s = asm.GetManifestResourceStream(resourceName);
    でStreamが取得できるので、そこからデータを読み出して、そのデータをファイルに書き出せばよいのではないでしょうか。


    > byte[] bs = System.IO.File.ReadAllBytes(resourceName);

    File.ReadAllBytesはファイルからのデータの読み出しなので、今回の場合には使えませんね。
    resourceNameはファイルのパスではありませんし。
記事No.34647 のレス /過去ログ60より / 関連記事表示
削除チェック/

■45934  Re[4]: timerについて
□投稿者/ 渋木宏明(ひどり) -(2010/01/22(Fri) 00:41:10)
>
    > >>この手順だと、「タイマーに誤差がある」場合、それが微小なものであってもどんどん累積してしまい、最終的には不都合なくらい大きな誤差になってしまいます。
    >>
    >>とすれば、どのように計算するのが望ましいのでしょうか?

    時間で管理するのではなく、時刻で管理するとか。
記事No.45882 のレス /過去ログ78より / 関連記事表示
削除チェック/

■88470  コントロールを自然に動かすには??
□投稿者/ 熊さん -(2018/09/02(Sun) 22:41:45)

    分類:[.NET 全般] 

    NumericUpDownを使って、
    PictureBoxのサイズを動かしたいと考えています。

    NumericUpDown1.Value
    に0〜1までの値が入っているとして、


    Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged

    PictureBox1.Top = 100 + CInt(500 * (1 - NumericUpDown1.Value) * 0.5)
    PictureBox1.Height = CInt(500 * NumericUpDown1.Value)

    End Sub

    のようにして、
    サイズを変更するコードを書きました。
    しかし、この方法だと、
    PictureBoxの位置をずらした後に、サイズを変更するコードとなっているため、
    一瞬だけ、PictureBoxが移動したのが見えてしまい、
    非常に不格好です。

    そのため、


    Me.SuspendLayout()

    PictureBox1.Top = 100 + CInt(500 * (1 - NumericUpDown1.Value) * 0.5)
    PictureBox1.Height = CInt(500 * NumericUpDown1.Value)

    Me.ResumeLayout(False)

    のように、コントロールの外観を変更している間
    フォームが描画されないようにしてみたのですが、
    やはり、変化はなく、PictureBoxの移動が目に見えてしまいます。

    Me.ResumeLayout(False)

    の前に
    Thread.Sleep(1000)
    を入れて、動作を確認してみたのですが、
    どうも
    Me.SuspendLayout()
    がうまく機能しておらず、
    Me.ResumeLayout(False)
    に入る前に、描画されてしまっているように思います。

    一体、どうすれば、コントロールの動きを同時に行うことができますか?

親記事 /過去ログ152より / 関連記事表示
削除チェック/

■88472  Re[1]: コントロールを自然に動かすには??
□投稿者/ Azulean -(2018/09/02(Sun) 23:10:14)
    Bounds プロパティで位置とサイズを一気に変えても見た目は変わらず…ですかね?
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88473  Re[1]: コントロールを自然に動かすには??
□投稿者/ 通りすがり -(2018/09/02(Sun) 23:42:38)
    No88470 (熊さん さん) に返信

    多分Boundsで用は足りると思うけど

    > Me.SuspendLayout()

    はコンテナのレイアウトロジックを停止させるものなのでコントロールの描画を止めるなら
    https://dobon.net/vb/dotnet/control/beginupdate.html
    あたりを参考に
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88502  Re[2]: コントロールを自然に動かすには??
□投稿者/ 熊さん -(2018/09/04(Tue) 12:18:39)

    ありがとうございます。

    PictureBoxの枠線や画像に関してはBoundsでうまくいきました。

    あと、PictureBoxの上に


    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles PictureBox1.Paint

    Dim g As Graphics = e.Graphics
    g.DrawLine(・・・)

    End Sub

    のようにしてラインを書いているので、ボックスのサイズ変更と同時に位置を調整する必要があります。

    PictureBox1.SetBounds(・・・)

    ’ライン位置を変更するコード

    PictureBox1.Refresh()

    とやってみたのですが、
    一瞬だけラインが動いてしまいます。

    BeginUpdate、EndUpdateメソッドを使ってみたのですが、
    なぜか、PictureBoxのサイズを変更すると、元あった線が消えずに残るため
    二重3重4重に枠線が表れてしまいます。
    PictureBoxはこれらのメソッドに対応していないのでしょうか?

    ちなみに
    ''' コントロールの再描画を停止させる
    Public Shared Sub BeginControlUpdate(control As Control)

    ''' コントロールの再描画を再開させる
    Public Shared Sub EndControlUpdate(control As Control)

    とありますが、停止させる方がEndで
    再開させる方がBeginだと思うのですが、
    Webページの誤植でしょうか?


記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88506  Re[3]: コントロールを自然に動かすには??
□投稿者/ 魔界の仮面弁士 -(2018/09/04(Tue) 13:59:58)
    No88502 (熊さん さん) に返信
    > なぜか、PictureBoxのサイズを変更すると、元あった線が消えずに残るため

    PictureBox 自身の事だとしたら、PictureBox1.Invalidate() を呼べば OK かと。

    PictureBox 自身ではなく、その親コントロールに PictureBox の残像が残るという状況なら、
    親の OnPaintBackground メソッドをオーバライドして握りつぶすと改善することがあります。
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88540  Re[4]: コントロールを自然に動かすには??
□投稿者/ 熊さん -(2018/09/06(Thu) 08:58:55)
    PictureBox1.Invalidate() を呼んでみましたがやはり残像が消えずに残ってしまいます。

    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
    ' 何もしない
    End Sub

    を試してみたところ、残像が消えないだけでなく
    フォームが真っ黒になってしまうのですが・・・
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88541  Re[5]: コントロールを自然に動かすには??
□投稿者/ 魔界の仮面弁士 -(2018/09/06(Thu) 10:21:25)
    2018/09/06(Thu) 10:23:05 編集(投稿者)

    No88540 (熊さん さん) に返信
    > PictureBox1.Invalidate() を呼んでみましたがやはり残像が消えずに残ってしまいます。

    No88506 の再確認になりますが、ここでいう「残像」というのは
     Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles PictureBox1.Paint
    で描かれた内容が残ってしまう、ということでよろしいでしょうか。

    それとも、PictureBox1 の外側(それを載せている Panel や Form 等)に対して
    移動前の位置に残像として残ってしまっている、ということなのでしょうか。


    後者だとしたら、親側を Invalidate あるいは Refresh するようにしてみてください。

    前者については、PictureBox1 自身を Invalidate あるいは Refresh しているので
    PictureBox1 の Paint イベントが誘発されるはずなのですが…それでも
    残像として残るようであれば、Paint が呼ばれた時点で、
    e.Grapchis の Clear メソッドを呼び出すようにしてみては如何でしょう。



    あと、フォーム上(というか UI スレッド)からは
    Thread.Sleep(1000) を呼ばないようにしましょう。
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88543  Re[5]: コントロールを自然に動かすには??
□投稿者/ 魔界の仮面弁士 -(2018/09/06(Thu) 14:25:18)
    No88540 (熊さん さん) に返信
    > PictureBox1.Invalidate() を呼んでみましたがやはり残像が消えずに残ってしまいます。
    
    現象を再現可能なサンプルを提示することはできますか?
    
    
    とりあえず当方でも、
     PictureBox1.SetBounds(-1, y, -1, h, BoundsSpecified.Y Or BoundsSpecified.Height)
    および
     PictureBox1.Bounds = New Rectangle(PictureBox1.Left, y, PictureBox1.Width, h)
    の 2 パターンで実験コードを書いてみましたが「残像」を確認できませんでした。
    
    ※検証環境:.NET Framwork 4.7.2 / VS2017 15.8.2 / Win10 ver1803
    
    
    Option Strict On
    Partial Public Class Form1
        Inherits Form
        Private WithEvents NumericUpDown1 As New NumericUpDown()
        Private WithEvents PictureBox1 As New PictureBox()
        Public Sub New()
            '説明のため、今回はデザイン時設定をコードで記載しています
            'InitializeComponent()
    
            NumericUpDown1.BeginInit()
            NumericUpDown1.Tag = "Initializing"
            NumericUpDown1.TextAlign = HorizontalAlignment.Right
            NumericUpDown1.DecimalPlaces = 2
            NumericUpDown1.Increment = 0.01D
            NumericUpDown1.Minimum = 0.2D
            NumericUpDown1.Value = 1D
            NumericUpDown1.Maximum = 1.2D
            NumericUpDown1.Font = New Font("Courier New", 21.0F)
            PictureBox1.BackColor = Color.White
            PictureBox1.BorderStyle = BorderStyle.FixedSingle
            PictureBox1.SetBounds(50, 175, 250, 500)
            PictureBox1.BackgroundImage = Icon.ToBitmap()
            PictureBox1.BackgroundImageLayout = ImageLayout.Zoom
            Controls.Add(NumericUpDown1)
            Controls.Add(PictureBox1)
            NumericUpDown1.EndInit()
            NumericUpDown1.Tag = Nothing
            Me.Size = New Size(400, 650)
    
            '初期化処理中に ValueChanged が処理されないよう、イベントを手動で割り当てている
            ResizePicture()
            AddHandler NumericUpDown1.ValueChanged, AddressOf NumericUpDown1_ValueChanged
        End Sub
    
        Private Sub ResizePicture()
            'PictureBox1.Top = 100 + CInt(500 * (1 - NumericUpDown1.Value) * 0.5)
            'PictureBox1.Height = CInt(500 * NumericUpDown1.Value)
            Dim y As Integer = 100 + CInt(250D * (1D - NumericUpDown1.Value))
            Dim h As Integer = CInt(500 * NumericUpDown1.Value)
    
            'PictureBox1.SetBounds(-1, y, -1, h, BoundsSpecified.Y Or BoundsSpecified.Height)
            PictureBox1.Bounds = New Rectangle(PictureBox1.Left, y, PictureBox1.Width, h)
    
            'リサイズされたので再描画を依頼
            PictureBox1.Invalidate()
        End Sub
    
        Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) 'Handles NumericUpDown1.ValueChanged
            ResizePicture()
        End Sub
    
        'DrawLine による描画処理。背景の塗り直しは行っていない。
        Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
            Dim r As Rectangle
    
            r = PictureBox1.ClientRectangle 'PictureBox 全体
            Using p As New Pen(Brushes.MediumTurquoise, 4)
                For y = r.Top To r.Bottom Step Math.Max(r.Height \ 20, 1)
                    e.Graphics.DrawLine(p, r.Left, y, r.Right, y)
                Next
            End Using
    
            r = e.ClipRectangle '可視エリアのみ
            Using b As New SolidBrush(Color.FromArgb(218, Color.LightPink)), p As New Pen(b, 2)
                For y = r.Top To r.Bottom Step Math.Max(r.Height \ 20, 1)
                    e.Graphics.DrawLine(p, r.Left, y, r.Right, y)
                Next
            End Using
        End Sub
    
    #Region "ClipRectangle が変更されたら再描画"
        Private Sub PictureBox1_Resize(sender As Object, e As EventArgs) Handles PictureBox1.Resize
            PictureBox1.Invalidate()
        End Sub
        Private Sub Form1_ResizeEnd(sender As Object, e As EventArgs) Handles Me.ResizeEnd
            PictureBox1.Refresh()
        End Sub
        Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
            PictureBox1.Invalidate()
        End Sub
    #End Region
    
    End Class
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88572  Re[6]: コントロールを自然に動かすには??
□投稿者/ 熊さん -(2018/09/08(Sat) 16:01:04)
    2018/09/08(Sat) 16:01:51 編集(投稿者)

    ありがとうございます。
    確かにこのコードだとほとんど残像が気になりませんね。

    以下のコードが残像の出るコードです。

    フォーム上に
    PictureBox1とNumericUpDown1を配置して
    ホイールでNumericUpDown1を回していただけますでしょうか?

    すると位置が変化するはずのない赤色の中央線がぴくぴく動くことがご確認いただけると思います。

    PictureBox1.Invalidate()


    ' PictureBox1.Refresh()
    すると少しましにはなるのですが
    やはりぴくぴく動いてしまいます。


    Public Class Form6


    Public YRate As Single

    Public ProfilePosition As New XY_Profile

    Public Class XY_Profile

    Property X_Int As Integer
    Property Y_Int As Integer

    End Class



    Private Sub Form6_Imaging_Load(sender As Object, e As EventArgs) Handles MyBase.Load


    PBox1 = PictureBox1.Bounds

    With NumericUpDown1
    .Minimum = 10
    .Maximum = 100
    .DecimalPlaces = 0
    .Increment = 3
    .Value = 100
    End With

    PictureBox1.SizeMode = PictureBoxSizeMode.Zoom


    ProfilePosition.X_Int = CInt((PictureBox1.Width - 3) / 2)
    ProfilePosition.Y_Int = CInt((PictureBox1.Height - 3) / 2)



    End Sub



    Private PBox1 As Rectangle


    Private pPen As New Pen(Color.FromArgb(60, Color.Red), 2)

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles PictureBox1.Paint

    Dim Pbox As PictureBox = CType(sender, PictureBox)

    Dim g As Graphics = e.Graphics
    g.DrawLine(pPen, 0, ProfilePosition.Y_Int, Pbox.Width, ProfilePosition.Y_Int)
    g.DrawLine(pPen, ProfilePosition.X_Int, 0, ProfilePosition.X_Int, Pbox.Height)

    End Sub



    Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged


    YRate = NumericUpDown1.Value / 100

    PictureBox1.SetBounds(PBox1.X, PBox1.Top + CInt(PBox1.Height * (1 - YRate) * 0.5), PBox1.Width, CInt(PBox1.Height * YRate))

    ProfilePosition.Y_Int = CInt(0.5 * (PictureBox1.Height - 4))

    ' PictureBox1.Refresh()

    PictureBox1.Invalidate()


    End Sub

    End Class
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88584  Re[7]: コントロールを自然に動かすには??
□投稿者/ 魔界の仮面弁士 -(2018/09/09(Sun) 01:09:10)
    2018/09/09(Sun) 04:49:21 編集(投稿者)

    No88572 (熊さん  さん) に返信
    > すると位置が変化するはずのない赤色の中央線がぴくぴく動くことがご確認いただけると思います。

    「位置がまったく変化していない」ことは確認済みでしょうか。

    たとえば、現在の処理方法で詰めていくのなら、
      PictureBox1.SetBounds(…)
      ProfilePosition.Y_Int = …
    の直後に
      Me.Text = CStr(PictureBox1.Top + ProfilePosition.Y_Int)
    などを置いてみて、NumericUpDown を動かしたときに
    タイトルバーに記載される値がブレないことを確認するなど。



    > PBox1.Top + CInt(PBox1.Height * (1 - YRate) * 0.5)
    上記の計算式の場合、YRate が Single なので、
    0.5 や 0.5R ではなく、0.5F と書いた方が良いですよ。


    さて、以下は提示頂いたコードとは別のやり方になるのですが:

    中央線は、PictureBox の位置に合わせて調整するとはいえ、
    Form 上から見れば、常に同じ位置にあるわけですよね。

    であれば Load 時にでも、その中央線の交点座標を、
    PictureBox1 の中での位置として保持するのではなく、
    「Form のクライアント座標」に変換して保持されては如何でしょう。

    そうすれば、NumericUpDown は PictureBox1 の位置調整に
    特化して処理できますので、描画処理も簡潔になりそうな気がします。


    ということで、書き直してみました。


    Public Class Form6
    Private pPen As Pen '十字線の描画用ペン
    Private PBox1 As Rectangle '100% の時の PictureBox1 の位置情報
    Private CenterPos As Point '十字線の中央位置(Formのクライアント領域基準)
    Private Sub Form6_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
    pPen.Dispose() '不要になった Pen の処分
    End Sub
    Private Sub Form6_Imaging_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    pPen = New Pen(Color.FromArgb(60, Color.Red), 2) '十字線描画用
    PBox1 = PictureBox1.Bounds '初期位置の保存

    '十字線の中央位置(PictureBoxのクライアント領域基準)
    Dim centerPic As New Point(PictureBox1.Width \ 2, PictureBox1.Height \ 2)

    '十字線の中央位置(Formのクライアント領域基準)
    CenterPos = centerPic + New Size(PictureBox1.Location)
    End Sub
    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles PictureBox1.Paint
    Dim Pbox As PictureBox = CType(sender, PictureBox)

    '十字線の中央位置(PictureBoxのクライアント領域基準)
    Dim xy = CenterPos - New Size(PictureBox1.Location)

    Dim g = e.Graphics
    g.DrawLine(pPen, 0, xy.Y, PictureBox1.Width, xy.Y)
    g.DrawLine(pPen, xy.X, 0, xy.X, PictureBox1.Height)
    End Sub

    Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
    If PBox1.IsEmpty Then
    Return 'ロード前なので何もしない
    End If

    '位置調整の「前」に、描画状態を無効化しておく
    PictureBox1.Invalidate()

    '位置調整
    Dim val As Integer = CInt(NumericUpDown1.Value) '10〜100
    Dim sz As New Size(PBox1.Width, PBox1.Height * val \ 100)
    Dim xy As New Point(PBox1.Left, PBox1.Top + (PBox1.Height - sz.Height) \ 2)
    PictureBox1.Bounds = New Rectangle(xy, sz)
    End Sub
    End Class


    なお元のコードでは、座標の計算時に、
    Decimal, Integer, Single, Double の型が混ざっていたので、
    勝手ながらすべて Integer のみで演算されるよう改修しています。

    ただし「CInt(z * 0.5)」を「z \ 2」で代用した関係上、
    NumericUpDown の値によっては、PictureBox1 の位置と大きさが
    ごく僅かにズレが生じることがあります。

    具体的には、「CInt(z * 0.5)」と「z \ 2」の計算を比較すると、
    z = 105 の場合は、どちらの計算でも 52 と算出されますが、
    z = 103 の場合は、前者が 52、後者は 51 となるというものです。
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88588  Re[8]: コントロールを自然に動かすには??
□投稿者/ 熊さん -(2018/09/09(Sun) 13:25:43)
    ありがとうございます。
    問題解決しました。


    ただ、少し以下気になった点です。


    > > PBox1.Top + CInt(PBox1.Height * (1 - YRate) * 0.5)
    > 上記の計算式の場合、YRate が Single なので、
    > 0.5 や 0.5R ではなく、0.5F と書いた方が良いですよ。

    これはなぜでしょうか?
    0.5Fとしなかった場合、どういう問題があり得ますか?
    確か、C++だと、エラーになるのでしたでしょうか?



    PictureBox1.Invalidate()

    PictureBox1.Bounds = New Rectangle(xy, sz)

    の前にありますが、

    PictureBox1.Invalidate()はPictureBox1に描画するように指令を出すためのコマンドのはずです。
    それなら、
    PictureBox1.Bounds = New Rectangle(xy, sz)
    の後でないと設定したサイズが描画されないのではないでしょうか?
    そもそも
    '位置調整の「前」に、描画状態を無効化しておく
    と、無効化しておく、と書いてあるのはなぜでしょうか?
    本来の機能と正反対ではありませんか?
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88589  Re[9]: コントロールを自然に動かすには??
□投稿者/ 熊さん -(2018/09/09(Sun) 13:28:53)

    後、もう一つ疑問です。

    Private Sub Form6_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
    pPen.Dispose() '不要になった Pen の処分
    End Sub

    フォームを閉じる時に、pPenを解放する処理が書かれてありますが、
    解放処理が必要な変数と不要な変数の違いは何でしょうか?

記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88593  Re[10]: コントロールを自然に動かすには??
□投稿者/ 魔界の仮面弁士 -(2018/09/09(Sun) 16:46:58)
    No88589 (熊さん さん) に返信
    > Private Sub Form6_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
    >   pPen.Dispose() '不要になった Pen の処分
    > End Sub
    > フォームを閉じる時に、pPenを解放する処理が書かれてありますが、
    > 解放処理が必要な変数と不要な変数の違いは何でしょうか?

    一口に答えるのは難しいのですが、ざっくり言うと、
    「アンマネージリソースを保持しているかどうか」でしょうか。

    こういったオブジェクトは多くの場合、IDisposable インターフェイスを通じて
    Dispose メソッドを有していますので、それを呼び出すようにします。

    たとえば、ファイルやデータベース接続などが分かりやすいかと思います。
    ファイルを開いたまま閉じなければ、他のアプリケーションがそれを開けません。
    データベース接続を開く一方で閉じずにいれば、接続資源が枯渇します。


    あるいは、Control や Form 等のオブジェクトも IDisposable です。

    たとえば ShowDialog メソッドの呼び出しにおいては、
     Using dlg As New Form2()
      dlg.ShowDialog(Me)
     End Using
    とすべきであり、最後に Dispose することなく
     Dim dlg As New Form2()
     dlg.ShowDialog(Me)
    とだけ書くのは NG です。
    ただし Show メソッドの場合は Dispose が自動的に呼ばれますので、明示的な Dispose は不要です。


    Control を動的に追加/削除する場合も同様で、
    意図的に .Controls.Remove あるいは .Clear するような場合には、
    取り除かれたコントロールを、明示的に Dispose しなければなりません。
    Remove せず、Form の Controls に登録したままであれば、Form が Dispose される時に
    子孫が連鎖的に Dispose されるので、明示的に Dispose する必要は無いですけれど。


    そして、Pen、Brush、Font、Grapchis、Bitmap などもまた、Dispose 対象です。

    ただし、Pens.Black や Brushes.Red などといったものに関しては、
    自身で作成したリソースでは無く、Shared メンバーで管理される共有資源なので
    この場合は Dispose してはいけません。(Dispose 後に再作成する手段がない)

    また、Grapchis についても、Dispose が必要となるのは、
    .CreateGraphics メソッドや Graphics.FromImage メソッドなどのように
    自身で作成したリソースだけです。Paint イベントの e.Graphics などは
    自身で作成したものではないので、勝手に Dispose してはいけません。


    ……ということで、Dispose メソッドがあれば常に呼び出すというわけでも
    無いという点が、こういった判断を難しくしています。
    StreamReader / StreamWriter なども、意図的に Dispose を呼ばないケースがありますし、
    DataSet / DataTable などのように、Dispose しても何も起きないものなどもあります。



    No88588 (熊さん さん) に返信
    >>> PBox1.Top + CInt(PBox1.Height * (1 - YRate) * 0.5)
    >>上記の計算式の場合、YRate が Single なので、
    >>0.5 や 0.5R ではなく、0.5F と書いた方が良いですよ。
    > これはなぜでしょうか?

    一言で言えば、「データ型を意識しましょう」ということです。
    Single 精度で演算したいのか、Double 精度で演算したいのか。

    0.5 や 0.5R や 0.5# というのは Double 型のリテラルであり、
    0.5F や 0.5! と書いた場合には Single 型のリテラルを意味します。
    0.5D や 0.5@ と書いた場合には Decimal 型のリテラルを意味します。


    先ほどの
     PBox1.Top + CInt(PBox1.Height * (1 - YRate) * 0.5)
    の型を見てみると、
     Integer + CInt( Integer * ( Integer - Single ) * Double )
    となっていますので、演算を進めていくと
     Integer + CInt( Integer * ( Single ) * Double )
     Integer + CInt( Single * Double )
     Integer + CInt( Double )
     Integer + Integer
    の精度で計算されることになりますね。



    >> YRate = NumericUpDown1.Value / 100
    この代入式も、左辺の型が Single ですので、現状は
     Single 変数 = Decimal 値 / Integer 値
    という計算式になっています。

    「Decimal / Integer」は Decimal 型の精度で演算される仕様であり、
    Single 変数 に Decimal 値を代入しようとしていることに注意してください。

    Single は Decimal よりも表せる範囲が広いため、
    この暗黙変換は Option Strict On でも成功します。
    しかし有効桁数の精度的には Single の方が荒く、その分誤差を生じます。
    あとは、この誤差をどう考えるかです。

    ※Decimal は 128bit のサイズを持つ型ですが、Single は 32bit しかありません。
    ※Decimal の有効桁数は約 28.899 桁、Single の有効桁数は約 7.2247 桁です。


    後々 Double 精度で演算したいなら、YRate も Double の方が手っ取り早いですし
    Single 精度で十分なら、先の座標計算も Single 型の計算式を組むべきでしょう。
    あるいは誤差を減らしたいなら、パフォーマンスさえ許容範囲なら Decimal が使えますし、
    あるいはパフォーマンス優先で、先のように Integer な演算式を組むこともできるわけです。

    Integer 単位の Point/Rectangle 型や
    Single 単位の PointF/RectangleF 型はあっても
    Double 単位の PointR/RectangleR 型が無いというのも
    型を選ぶ指針になるのではないでしょうか。


    Single や Double は、2 進小数型ですので、0.50 や 0.25 は正しく保持できても、
    0.01 という値は有限桁で表せず、わずかに誤差を含んでしまいます。
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88592  Re[9]: コントロールを自然に動かすには??
□投稿者/ 魔界の仮面弁士 -(2018/09/09(Sun) 16:03:28)
    No88588 (熊さん さん) に返信
    > 問題解決しました。
    なお No88572 で投稿いただいたコードだと、
    >>   Me.Text = CStr(PictureBox1.Top + ProfilePosition.Y_Int)
    の実験で、中央線の座標に ±1 程度のブレが見られましたので、
    そもそもの計算で誤差が生じていた、というのも原因の一つかと思います。
    (それは残像ではなく、計算ミスということになりそうですが)


    > PictureBox1.Invalidate()はPictureBox1に描画するように指令を出すためのコマンドのはずです。
    ちょっと違います。


    【Invalidate】の仕事は、そのウィンドウ内に『更新リージョン』を作成するだけであり、
    正確には描画依頼そのものではありません。

    ざっくり言えば、「現在の描画内容が無効である」とマーキングするためのもの。
    今回は引数無しで呼び出しているので、領域すべてが無効化されます。
    https://msdn.microsoft.com/ja-jp/library/cc410421.aspx


    【Update】は、その更新リージョンが空ではない場合に、そのコントロールに対して
    WM_PAINT ウィンドウメッセージを送信してクライアント領域を更新します。
    これにより Paint イベントが誘発されます。
    (更新すべき領域が何もなければ、呼び出しても何も起きません)

    ウィンドウメッセージは通常、待機行列にキューイングされた上で、
    アイドル時に順次処理されるようになっているのですが、Update メソッドを
    呼び出した場合は、その待機行列を通さずに直接再描画メッセージが飛んできます。
    https://msdn.microsoft.com/ja-jp/library/cc428780.aspx


    【Refresh】は、Invalidate + Update と同義です。
    直ちに再描画を行い時にのみ呼び出します。


    PictureBox の上に他のウインドウが覆いかぶさっていて、それが取り除かれた時に
    再描画されるのも、その重なっていた領域分の更新リージョンが生成されるためです。
    この場合は明示的に Update を呼ばずとも、アイドル時に自動的に Paint イベントが呼ばれます。


    >> '位置調整の「前」に、描画状態を無効化しておく
    >> PictureBox1.Invalidate()
    > が
    > PictureBox1.Bounds = New Rectangle(xy, sz)
    > の前にありますが、
    Update や Refresh ではなく、Invalidate である点がミソです。


    > PictureBox1.Bounds = New Rectangle(xy, sz)
    > の後でないと設定したサイズが描画されないのではないでしょうか?
    Bounds の直後に呼ぶとしたら、Invalidate ではなく Update または Refresh ですよ。

    今回は Update を呼び出していませんが、それはリサイズ直後に End Sub しているからです。
    アイドル時に Invalidate された領域への再描画が発生するので、
    あえて Update を呼ぶ必要も無いという訳ですね。


    それともう一つ。現在の描画状態を無効化せずに Top 位置を変えると、
    以前描いた中央線ごと移動してしまうので、一瞬、正しくない位置に線があるように
    見えてしまうという問題もあります。だからこそ、「直前」の無効化が重要となります。

    直前には Invalidate を呼ばず、直後に呼び出してみるとか、
    直前の Invalidate を Refresh に変えて呼び出してみると、
    これらの違いを体感できるかと思います。
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88595  Re[10]: コントロールを自然に動かすには??
□投稿者/ 熊さん -(2018/09/09(Sun) 19:47:15)


    ありがとうございます。

    ただ、【Invalidate】のことがやはりよく理解できませんでした。

    Invalidateとは更新予約するもので
    Refleshは即時に更新するものであることは分かります。

    例えば、上でご呈示くださったコードでは

    PictureBox1.Bounds = New Rectangle(PictureBox1.Left, y, PictureBox1.Width, h)

    'リサイズされたので再描画を依頼
    PictureBox1.Invalidate()

    リサイズの後に使用しているのはなぜでしょうか?

    また、他のサンプルプログラムを見ていても、後に出てくるのがほとんどだと思います。
    http://wisdom.sakura.ne.jp/system/msnet/msnet_win21.html
    https://devlights.hatenablog.com/entry/20080509/p1


    Boundsの後にもInvalidateを入れてみたりして、
    うまく描画されず、Boundsの前である必要があることは分かるのですが
    なぜ「今回だけ」前に入れるのかが分かりません。

    前に入れる場合と後ろに入れる場合の使い分けについて教えていただけないでしょうか?


    例えば、画像を表示したい場合、

    With PBox

    .Image = img
    .Invalidate()

    End With

    Invalidateを
    .Image = img

    の前に入れても後に入れても、同じように動作しますが
    どちらに入れるのが正しいのでしょうか?






記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88596  Re[11]: コントロールを自然に動かすには??
□投稿者/ 魔界の仮面弁士 -(2018/09/09(Sun) 20:22:17)
    No88595 (熊さん さん) に返信
    > リサイズの後に使用しているのはなぜでしょうか?
    特に意図は無いですが、強いて言えば、前後どちらであっても、
    気になるような差が出なかったら、という程度ですね。

    先のように、移動前後で座標がまったくずれないようにしたい場合には
    気にかけた方が良いと思います。


    > http://wisdom.sakura.ne.jp/system/msnet/msnet_win21.html
    これは、クライアント領域の再描画が行われているだけであって、
    ウィンドウ位置が変化しているわけではないのですから、
    今回の話とは関係無いですよね。



    > 例えば、画像を表示したい場合、
    > の前に入れても後に入れても、同じように動作しますが
    > どちらに入れるのが正しいのでしょうか?
    どちらも不要かと思いますよ。
    PitureBox.Image は、新しい画像がセットされたときに
    内部で自動的に Invalidate を呼び出していますから。
記事No.88470 のレス /過去ログ152より / 関連記事表示
削除チェック/

次の20件>

<< 0 | 1 >>

パスワード/

- Child Tree -