我想画横向间距、纵向间距均为1mm的网格线,也就是每一个小格子是1mm×1mm的正方形,现在有两点需要问大家。
1、我想打印出的网格线是1mm×1mm的正方形,请问对不同打印分辨率下,该怎么做。
2、如果要在显示屏上显示实际是1mm×1mm的正方形,那么在不同分辨率下,要显示出和实际物理尺寸1mm×1mm一致的方格,该怎么做。

解决方案 »

  1.   

    96DPI表示:每英寸96像素
    1英寸 = 2.54 厘米桌面 -> 右键 -> 设置 -> 高级 -> 常规 能看到DPI
      

  2.   

    CDC SetMapMode MM_LOMETRIC   
      

  3.   

    在屏幕上不可能准确打出1mm×1mm。但在打印机上可以。
    我给你推荐我以前做的程序。在打印机上,打印 1mm×1mm 或 0.1x0.1Inch的格子。
    可以做尺子用,所以我叫它尺子。
    你做一个sdi的一个工程Ruler,把下面的RulerView.cpp替换进去。
    再在资源了增加一个菜单 IDMENU_SCALE_TYPE 
    下面的 OnScaleType()函数,就可以执行了,用它来选择 1mm×1mm 或 0.1x0.1Inch。---------------------------------------------------------------------------------------// RulerView.cpp : CRulerView クラスの動作の定義を行います。
    //#include "stdafx.h"
    #include "Ruler.h"#include "RulerDoc.h"
    #include "RulerView.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CRulerViewIMPLEMENT_DYNCREATE(CRulerView, CView)BEGIN_MESSAGE_MAP(CRulerView, CView)
        //{{AFX_MSG_MAP(CRulerView)
        ON_COMMAND(IDMENU_SCALE_TYPE, OnScaleType)
        ON_UPDATE_COMMAND_UI(IDMENU_SCALE_TYPE, OnUpdateScaleType)
        //}}AFX_MSG_MAP
        // 標準印刷コマンド
        ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CRulerView クラスの構築/消滅CRulerView::CRulerView()
    {
        // TODO: この場所に構築用のコードを追加してください。}CRulerView::~CRulerView()
    {
    }BOOL CRulerView::PreCreateWindow(CREATESTRUCT& cs)
    {
        // TODO: この位置で CREATESTRUCT cs を修正して Window クラスまたはスタイルを
        //  修正してください。    return CView::PreCreateWindow(cs);
    }#define RULER_WIDTH_MM            180
    #define RULER_HEIHGT_MM            240
    #define RULER_WIDTH_INCH_10        70
    #define RULER_HEIHGT_INCH_10    90
    BOOL g_bMetric = TRUE;/////////////////////////////////////////////////////////////////////////////
    // CRulerView クラスの描画void CRulerView::OnDraw(CDC* pDC)
    {
        CRulerDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        // TODO: この場所にネイティブ データ用の描画コードを追加します。    int i;
        CPen Pen10;
        CPen Pen5;
        CPen Pen1;
        CPen* pOldPen;    int RULER_WIDTH;
        int RULER_HEIHGT;    if (g_bMetric)
        {
            RULER_WIDTH = RULER_WIDTH_MM;    
            RULER_HEIHGT = RULER_HEIHGT_MM;    
        }
        else
        {
            RULER_WIDTH = RULER_WIDTH_INCH_10;    
            RULER_HEIHGT = RULER_HEIHGT_INCH_10;    
        }    Pen10.CreatePen(PS_SOLID, 3, (COLORREF)0xFF0000);
        Pen5.CreatePen(PS_SOLID, 2, (COLORREF)0xFF0000);
        Pen1.CreatePen(PS_SOLID, 1, (COLORREF)0xFF0000);
        
        int nMapModeOld;    if (g_bMetric)
        {
            nMapModeOld = pDC->SetMapMode(MM_LOMETRIC);
            pDC->SetWindowOrg(-254/2, 254/2);
        }
        else
        {
            nMapModeOld = pDC->SetMapMode(MM_LOENGLISH);
            pDC->SetWindowOrg(-50, 50);
        }    for (i = 0; i <= RULER_HEIHGT; i ++)
        {
            if (!(i % 10))
            {
                pOldPen = pDC->SelectObject(&Pen10);
                CString str;
                str.Format("%2d", i / 10);
                if (g_bMetric)
                    pDC->TextOut(-80, -i * 10 + 5, str); 
                else
                    pDC->TextOut(-31, -i * 10 + 2, str);         }
            else if (!(i % 5))
                pOldPen = pDC->SelectObject(&Pen5);
            else
                pOldPen = pDC->SelectObject(&Pen1);        pDC->MoveTo(0, -i * 10);
            pDC->LineTo(RULER_WIDTH * 10, -i * 10);
            pDC->SelectObject(pOldPen);
        }    for (i = 0; i <= RULER_WIDTH; i ++)
        {
            if (!(i % 10))
            {
                pOldPen = pDC->SelectObject(&Pen10);
                CString str;
                str.Format("%d", i / 10);
                if (g_bMetric)
                    pDC->TextOut(i * 10 - 10, 80, str); 
                else
                    pDC->TextOut(i * 10 - 2, 31, str);         }        else if (!(i % 5))
                pOldPen = pDC->SelectObject(&Pen5);
            else
                pOldPen = pDC->SelectObject(&Pen1);        pDC->MoveTo(i * 10, 0);
            pDC->LineTo(i * 10, -RULER_HEIHGT * 10);
            pDC->SelectObject(pOldPen);
        }
        pDC->SetWindowOrg(0, 0);
        pDC->SetMapMode(nMapModeOld);
    }/////////////////////////////////////////////////////////////////////////////
    // CRulerView クラスの印刷BOOL CRulerView::OnPreparePrinting(CPrintInfo* pInfo)
    {
        // デフォルトの印刷準備
        return DoPreparePrinting(pInfo);
    }void CRulerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
        // TODO: 印刷前の特別な初期化処理を追加してください。
    }void CRulerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
        // TODO: 印刷後の後処理を追加してください。
    }/////////////////////////////////////////////////////////////////////////////
    // CRulerView クラスの診断#ifdef _DEBUG
    void CRulerView::AssertValid() const
    {
        CView::AssertValid();
    }void CRulerView::Dump(CDumpContext& dc) const
    {
        CView::Dump(dc);
    }CRulerDoc* CRulerView::GetDocument() // 非デバッグ バージョンはインラインです。
    {
        ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRulerDoc)));
        return (CRulerDoc*)m_pDocument;
    }
    #endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
    // CRulerView クラスのメッセージ ハンドラvoid CRulerView::OnScaleType() 
    {
        // TODO: この位置にコマンド ハンドラ用のコードを追加してください
        g_bMetric = !g_bMetric;    
        Invalidate();
    }void CRulerView::OnUpdateScaleType(CCmdUI* pCmdUI) 
    {
        if (g_bMetric)
            pCmdUI->SetCheck(TRUE);
        else
            pCmdUI->SetCheck(FALSE);
    }
      

  4.   

    // RulerView.h : CRulerView クラスの宣言およびインターフェイスの定義をします。
    //
    /////////////////////////////////////////////////////////////////////////////#if !defined(AFX_RULERVIEW_H__ED64FB17_2E60_4FA5_B16E_346458184D99__INCLUDED_)
    #define AFX_RULERVIEW_H__ED64FB17_2E60_4FA5_B16E_346458184D99__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    class CRulerView : public CView
    {
    protected: // シリアライズ機能のみから作成します。
        CRulerView();
        DECLARE_DYNCREATE(CRulerView)// アトリビュート
    public:
        CRulerDoc* GetDocument();// オペレーション
    public:// オーバーライド
        // ClassWizard は仮想関数のオーバーライドを生成します。
        //{{AFX_VIRTUAL(CRulerView)
        public:
        virtual void OnDraw(CDC* pDC);  // このビューを描画する際にオーバーライドされます。
        virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
        protected:
        virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
        virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
        virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
        //}}AFX_VIRTUAL// インプリメンテーション
    public:
        virtual ~CRulerView();
    #ifdef _DEBUG
        virtual void AssertValid() const;
        virtual void Dump(CDumpContext& dc) const;
    #endifprotected:// 生成されたメッセージ マップ関数
    protected:
        //{{AFX_MSG(CRulerView)
        afx_msg void OnScaleType();
        afx_msg void OnUpdateScaleType(CCmdUI* pCmdUI);
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    };#ifndef _DEBUG  // RulerView.cpp ファイルがデバッグ環境の時使用されます。
    inline CRulerDoc* CRulerView::GetDocument()
       { return (CRulerDoc*)m_pDocument; }
    #endif///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。#endif // !defined(AFX_RULERVIEW_H__ED64FB17_2E60_4FA5_B16E_346458184D99__INCLUDED_)
      

  5.   

    获取打印机设备环境变量,然后就和画图一样的操作了!你要打印一个1mm*1mm的方框,那就换算一下1mm对应多少像素,然后直接MOVETO  LINETO就行了
      

  6.   

    忘了补充一下,你要根据分辨率来设置,可以使用DEVMODE结构里的参数,然后获取打印机设备信息,计算出一个系数,你的程序里乘以这个系数就可以应付任何分辨率的打印机了
      

  7.   

    To softist,您好,您的打印程序我看了,但是我现在打印出来的格子还是长方形的,怎么才能打印出1mm*1mm的方格子呢,请您指点,多谢
      

  8.   

    To softist,,您的打印程序中,下面几个宏定义我不明白,按照您的设置能获得1mm*1mm吗
    #define RULER_WIDTH_MM            180 
    #define RULER_HEIHGT_MM            240 
    #define RULER_WIDTH_INCH_10        70 
    #define RULER_HEIHGT_INCH_10    90 
      

  9.   

    打印坐标紙(VC++)
    http://www.softist.com/programemo/graph-paper/graph-paper.htm
    我已经上传了整个工程文件。