2016-05-05 12 views
-2

私はMM_ANISTROPICを使用して画像/テキストなどを拡張しようとすると、私がやったことは以下であるのですSetWindowExtExのスケーリングが間違っているのはなぜですか?

Iを(構文は少し奇妙である場合の方法によって、それはとても擬似コードとして以下扱うデルファイ出身です)次のコードでは、PaintBoxの幅の70%、高さの30%の矩形を生成することが期待されますが、そうではありません。

SetMapMode(hdc,MM_ANISOTROPIC); 
SetWindowExtEx(hdc,100,100,0); 
SetViewportExtEx(hdc,70,30,0); 
Rectangle(hdc, 0,0,PaintBox.width-1,PaintBox.Height-1); 

SetWindowExtExは91を持っている代わりに、そのパラメータとして100(以下に示すように)、それは全く私には意味をなさないれ、動作するように、一方で私は、コードを変更、場合...

SetMapMode(hdc,MM_ANISOTROPIC); 
SetWindowExtEx(hdc,91,91,0); 
SetViewportExtEx(hdc,70,30,0); 
Rectangle(hdc, 0,0,PaintBox.width-1,PaintBox.Height-1); 

私の正気のテストケースは、以下の擬似コード

SetMapMode(hdc,MM_TEXT); 
DrawLine(hdc,Round(PaintBox.width*0.7),0,Round(PaintBox.width*0.7),PaintBox.Height-1); 
DrawLine(hdc,0,Round(PaintBox.height*0.3),PaintBox.width-1,Round(PaintBox.height*0.3)); 

を追加することでした私は、これが私の元のRectangleの下/下端を上書きすると期待しているだろうが、それは私がない限りませんその91,91 SetWindowExtExを使用します。

誰でもこれを複製できますか?

さらに編集してください:私は擬似コードを与えてから非デルファイのユーザーにもっとアクセスしやすいようにしましたが、私のコメント作成者の一人は、それがデルファイのクールークであるという私の主張が本当かどうか。

プロジェクト全体が矩形ペイントボックスとVCLフォームから構成は、それが中心にので、すべてその周りにスペースが滴下し、そののOnPaintイベントがthis image:その結果、下のコードに設定した:

procedure TForm11.PaintBox2Paint(Sender: TObject); 
    var 
     hdc:THandle; 
     res:TPoint; 

    procedure SetupMapMode; 
    begin 
     SetMapMode(hdc,MM_ANISOTROPIC); 
     SetWindowExtEx(hdc,100,100,0); 
     SetViewportExtEx(hdc,70,30,0); 
    // These lines are required when we're painting to a TPaintBox but can't be used 
    // if we're paiting to a TPanel and they were NOT in my original question but only 
    // got added as part of the answer 
    // SetViewportOrgEx(hdc,PaintBox2.Left,PaintBox2.Top,@ZeroPoint); 
    // SetWindowOrgEx(hdc,0,0,@ZeroPoint); 
    end; 

    begin 
     //draw a rectangle to frame the Paintbox Surface 
     PaintBox2.Canvas.Pen.Style:=psSolid; 
     PaintBox2.Canvas.Pen.width:=2; 
     PaintBox2.Canvas.Pen.Color:=clGreen; 
     PaintBox2.Canvas.Brush.Style:=bsClear; 
     PaintBox2.Canvas.Rectangle(0,0,PaintBox2.Width-1,PaintBox2.Height-1); 
     PaintBox2.Canvas.Brush.Style:=bsSolid; 

     //initialize convenience variable 
     hdc:=PaintBox2.Canvas.Handle; 
     SetTextAlign(hdc,TA_LEFT); 

    //as doing things to the PaintBox2.Canvas via Delphi's interface tends to reset 
    //everything, I'm ensuring the map mode gets set **immediately** before 
    //each drawing call 
     SetupMapMode; 
    /// Draw Text at the bottom of the PaintBox2.Canvas (though as it's mapped it 
    /// SHOULD be 1/3 of the way down and much smaller instead) 
     TextOut(hdc,200,PaintBox2.Height-PaintBox2.Canvas.TextHeight('Ap'),'Hello, World!',13); 
     PaintBox2.Canvas.Pen.Color:=clblue; 
     PaintBox2.Canvas.Brush.Style:=bsClear; 
    //ensure it's set before doing the rectangle 
     SetupMapMode; 
    // Redraw the same rectangle as before but in the mapped mode 
     Rectangle(hdc, 0,0,PaintBox2.Width-1,PaintBox2.Height-1); 
     PaintBox2.Canvas.Brush.Style:=bsSolid; 
    //reset the map mode to normal 
     SetMapMode(hdc,MM_Text); 
    //draw text at the "same" position as before but unmapped... 
     TextOut(hdc,200,PaintBox2.Height-PaintBox2.Canvas.TextHeight('Ap'),'Goodbye, World!',15); 

    //Draw lines exactly at 70% of the way across and 30% of the way down 
    //if this works as expected they should overwrite the right and bottom 
    //borders of the rectangle drawn in the mapped mode 
     PaintBox2.Canvas.Pen.Color:=RGB(0,255,255); 
     PaintBox2.Canvas.MoveTo(Round(PaintBox2.Width*0.7),0); 
     PaintBox2.Canvas.LineTo(Round(PaintBox2.Width*0.7),PaintBox2.Height); 
     PaintBox2.Canvas.MoveTo(0,Round(PaintBox2.Height*0.3)); 
     PaintBox2.Canvas.LineTo(PaintBox2.Width,Round(PaintBox2.Height*0.3)); 
    end; 
+0

'PaintBox.Width-1、PaintBox.Height-1'の代わりに' Paintbox.Width、PaintBox.Height'が必要です。 「長方形」には、図面の下または右の座標は含まれません。 –

+0

あなたのアプリケーションはDPI対応ではないかもしれません。参照してください[リンク](https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx) –

+0

Drat、私はあなたが何かになるかもしれないと思ったが、私もこれまでアプリケーションの互換性プロパティを設定して640x480モードで実行するようになりましたが、違いはありませんでした。誰でもこれを複製できますか?元の質問にテストケースを追加しました。 –

答えて

0

大丈夫私は次のことが必要なのか分かりません。デルファイの奇妙なことかもしれませんが、TPaintBoxをComponentではなくTGraphicControlで使用しています。この全体のマッピングモードがどのように機能するのですか?ただし、次のコードを追加した場合:

ZeroPoint:=TPoint.Zero; 
SetViewportOrgEx(hdc,PaintBox1.Left,PaintBox1.Top,@ZeroPoint); 
SetWindowOrgEx(hdc,0,0,@ZeroPoint); 

次に、すべてが期待どおりに表示されます。なぜこれが必要であるかについて誰でも説明がありますか?

編集:はい、私は部分的な説明があります。それは私が描いていたコントロールがTPaintBoxであることと関係しています。TPaintBoxはTWinControlではなくTGraphicコントロールです。対象:

TGraphicControlは、すべての軽量コントロールの基本クラスです。

TGraphicControlは、キーボード入力を受け入れる機能や他のコントロールを含む必要のない簡単な軽量コントロールをサポートしています。軽量コントロールはWindowsのスクリーンオブジェクトをラップしないので、TWinControlに基づくコントロールよりも速く、ユーザーのリソースが少なくなります。このように

、彼らは別のキャンバスを持っているように見えますが、私は、独自のWindowsのDCを所有してのTWinControlの子孫に切り替えたときに、私はこの、彼らは本当に理由で、フォームのキャンバスを共有していることを感じてこっそりしていますViewpointOrgを設定せずにディスプレイが期待どおりに機能しました。

結局のところ、デルファイの奇抜でした...!

+0

*デルファイの奇妙なことではありません。 Delphiは、直接のWinAPI呼び出しに干渉したり影響を与えたりしません。 –

+0

実際、私はそれが(デルファイの素早い)と判断しました!この問題は実際にTPaintBoxコンポーネントで発生しましたが、完全に独立したキャンバスを持つように見えますが、明らかに真実ではありません。私が塗装ルーチンをオーバーライドしたTPanelで描画面を置き換えると、問題はなくなり、 'SetViewportOrgEx(hdc、PaintBox1.Left、PaintBox1.Top、@ZeroPoint); SetWindowOrgEx(hdc、0,0、@ZeroPoint) 'は、あなたが疑わしい問題を引き起こしました。つまり、スケーリングされたイメージがどこで開始されたかをオフセットします。 –

+0

私はまだそれがデルファイのクールークだとは思わない。私はそれがあなたのコードの問題だと思いますが、どちらの方法でも証明できる質問や答えにMCVEを提供できませんでした。 TPaintBoxは**特に**描画されるように設計されています(TPaintBoxという名前になっています)。あなたの質問と回答の両方で、コンテキスト外で不完全なコードのスニペットを投稿しました。あなたが含まれていないコードに問題がある可能性があります。 –

関連する問題