none
実線以外の線種描画と線幅1以上について RRS feed

  • 質問

  • VC++2010 MFCで開発しております。

    線幅1以上を指定した場合、デバイス単位で1以上とならない場合には、指定した線種が使用でき、
    1以上になった場合は、PS_SOLIDが適用されることは理解しました。

    CMyView::OnDraw関数の直下で次のポリラインを引いています。
    線幅:3、線種:破線
    マッピングモード:MM_LOMETRIC

    	{
    		pDC->SetMapMode(MM_LOMETRIC);
    	
    		CPen pen;
    		pen.CreatePen( 1, 5, RGB(0,0,0));
    		CPen* pOldpen = pDC->SelectObject( &pen );
    
    		CPoint pPntDim[7];
    		pPntDim[0].x=480; pPntDim[0].y=-876;
    		pPntDim[1].x=763; pPntDim[1].y=-792;
    		pPntDim[2].x=1047; pPntDim[2].y=-709;
    		pPntDim[3].x=1444; pPntDim[3].y=-625;
    		pPntDim[4].x=1842; pPntDim[4].y=-541;
    		pPntDim[5].x=2239; pPntDim[4].y=-458;
    		pPntDim[6].x=2636; pPntDim[4].y=-374;
    
    		pDC->Polyline( pPntDim, _countof(pPntDim));
    
    		// ペンとブラシを元に戻す
    		if( pOldpen ){
    			pDC->SelectObject( pOldpen );
    		}
    		pen.DeleteObject();
    	}

    次の環境でテストしてみると異なる描画となります。
    ともに解像度は、1280*1024となっています。

    デスクトップPC+ディスプレイ(1280*1024(推奨))=破線で描画される
    ノートPC(1280*1024)=実線で描画される

    これは何が原因となるのでしょうか?

    2019年7月11日 5:10

すべての返信

  • 使用している Display Adapter Driver の違いで起きているのでは?
    とりあえず差異が発生している双方の PC に対して、Device Manager 上で現在使用している "ディスプレイ アダプター" を無効にし、Display Adapter Driver に Windows 標準の basicdisplay.sys が使用される環境にし、それで該当プログラムでの検証を行ってみることをお勧めします。
    2019年7月11日 8:06
  • Win32SDKのCreatePen()関数の説明では、

    引用-->
    PS_DASH、PS_DOT、PS_DASHDOT、PS_DASHDOTDOT のいずれかのスタイルを指定し、1 より大きな幅を指定した場合、CreatePen 関数は、PS_SOLID スタイルと指定された幅を持つペンを返します。
    <--引用

    とあるので、本件のコード pen.CreatePen( 1, 5, RGB(0,0,0));は
    pen.CreatePen( PS_DASH, 5, RGB(0,0,0));
    と解釈され、説明の通りPS_SOLIDの線が描画されるはずです。
    従って、次の解釈がもっともらしいと考えられます。

    (1)デスクトップPCでは、幅1以下の破線を指定したペンで描画された。
    (2)ノートPCでは、実線のペンで描画された。
    (3)従って、両者ではおそらく異なる実行ファイルが実行された。

    この様な比較を行う場合には、タイムスタンプなどで確認できる
    完全に同一の実行ファイルで試験すべきですが、この点は万全でしょうか。

    最後に、
    「線幅1以上・・・」ではなく「線幅1を超える・・・」ですね。
    細かいことですが、まったく異なるので指摘しておきます。

    2019年7月11日 9:39
  • ご返事ありがとうございます。

    まず訂正ですが、描画で使われたPENの線幅は「3」でした。

    pen.CreatePen( PS_DASH, 3, RGB(0,0,0));

    また、線幅に関しては、デバイス単位で「1」を超えるとき、PS_SOLIDが適用される仕様だっただと思います。
    論理値の「3」を渡して、内部で論理値からデバイス値に変換されたとき、
    「1」以下だったら、線幅が「1」となり、指定した線種が反映され、
    「1」を超えるデバイス値なった時、線種が「PS_SOLID」になると思っています。

    ディスプレイドライバー関連についてはまた調査してみます。

    2019年7月12日 1:17
  • 指摘するの面倒だったので、あえてコメントしませんでしたが、誤解されている人もいるようなので。。。。

    > ともに解像度は、1280*1024となっています。

    ディプレイ解像度のこの値は、Pixel 単位であって Dot 単位ではないと思います。
    つまり同じ「1280*1024」であっても、Dot 単位。。。。すなわち Device Unit に変換したい場合、その値は個々のデバイス能力に依存して変化する可能性がある。
    なので、デバイス能力を同一化するために、Windows Inbox Driver である "basicdisplay.sys" で試してみるのがいいかと。
    2019年7月12日 1:59
  • Brilliaさん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    ご質問いただいた件ですが、その後いかがでしょうか。
    お馬鹿さんと仲澤@失業者さんから寄せられた投稿はお役に立ちましたか。

    参考になった回答には [回答としてマーク] をお願い致します。

    設定いただくことで、
    他のユーザーもお役に立つ回答を見つけやすくなります。

    お手数ですが、ご協力の程どうかよろしくお願いいたします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2019年7月17日 5:52
    モデレータ