Mfc. Координаты Scroll окна и Потоки.

Тема в разделе "MS Visual C++", создана пользователем OberonTSM, 8 дек 2007.

Статус темы:
Закрыта.
  1. OberonTSM

    OberonTSM Гость

    Проблема такая:
    Есть Приложение, вычисляющее точку оптимума функции по методу симплекса. объект вида - скроллинговый, причём размер больше размера экрана, то есть скролл нужен всегда. В главном окне в OnDraw рисуются координатные оси для трёх графиков. Также есть отдальный поток, рисующий сам процесс поиска методом симплекса (рисует наглядно, то есть шаг за шагом, по типу анимации). Собственно суть проблемы в том, что при любом скролле вниз координатная система для потока меняется и точка (0,0) совпадает с левым верхним углом ОТОБРАЖАЕМОЙ В ДАННЫЙ МОМЕНТ части объекта вида. А координатные оси остаются на своих местах. Соответственно
    следующий после прокрутки вниз шаг графика рисуется ниже чем надо. Как сделать так чтобы координаты для потока были постоянными и не зависили от скроллинга и отображаемой части объекта вида? Возможно ошибка в контексте устройства... Пожалуйста, подскажите что и где надо поменять\дописать...

    Также интересно, как сделать чтобы прис выходе за границу области где должен быть рисунок (когда сильно прокручиваешь вниз), графическая информация потока не стиралась а оставалась нарисованной.
    вот код потока и метода OnDraw:
    Код (Text):
    ///////////////////////////////////////////////////////////////////////////////////////////////////

    Объявление класса
    class CSimplexView : public CScrollView
    {
    protected: // create from serialization only
    CSimplexView();
    DECLARE_DYNCREATE(CSimplexView)

    // Attributes
    public:
    CSimplexDoc* GetDocument();

    // Operations
    public:
    CClientDC *m_pDC;       // óêàçàòåëü íà êîíòåêñò êëèåíòñêîé ÷àñòè îêíà
    CRITICAL_SECTION m_ClientDCLock;    // êðèòè÷åñêàÿ ñåêöèÿ
    //  int m_nThreadCounter;       // ñ÷åò÷èê ÷èñëà çàïóùåííûõ ïîòîêîâ
    bool m_bWorking;   
    int ViewCheck;
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CSimplexView)
    public:
    virtual void OnDraw(CDC* pDC); // overridden to draw this view
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
    virtual void OnInitialUpdate(); // called first time after construct
    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
    //}}AFX_VIRTUAL

    // Implementation
    public:
    virtual ~CSimplexView();
    #ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
    #endif


    // SimplexView.cpp : implementation of the CSimplexView class
    //

    #include "stdafx.h"
    #include "Simplex.h"

    #include "SimplexDoc.h"
    #include "SimplexView.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    /////////////////////////////////////////////////////////////////////////////
    // CSimplexView

    IMPLEMENT_DYNCREATE(CSimplexView, CScrollView)

    BEGIN_MESSAGE_MAP(CSimplexView, CScrollView)
    //{{AFX_MSG_MAP(CSimplexView)
    ON_COMMAND(ID_VIEW_GRAPH, OnViewGraph)
    ON_COMMAND(ID_VIEW_TABLE, OnViewTable)
    ON_WM_CREATE()
    ON_WM_DESTROY()
    ON_UPDATE_COMMAND_UI(ID_VIEW_SEARCHPROCESS, OnUpdateViewSearchprocess)
    ON_COMMAND(ID_VIEW_SEARCHPROCESS, OnViewSearchprocess)
    //}}AFX_MSG_MAP
    // Standard printing commands
    ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CSimplexView construction/destruction

    CSimplexView::CSimplexView()
    {
    // TODO: add construction code here
    ViewCheck=0;
    m_pDC = 0;
    m_bWorking = false;
    // m_nThreadCounter = 0;
    InitializeCriticalSection(&m_ClientDCLock);

    }

    CSimplexView::~CSimplexView()
    {
    DeleteCriticalSection(&m_ClientDCLock);
    }

    BOOL CSimplexView::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs

    return CScrollView::PreCreateWindow(cs);
    }

    /////////////////////////////////////////////////////////////////////////////
    // CSimplexView drawing

    UINT SearchThread(LPVOID pParam)
    {
    CSimplexView* pView = (CSimplexView*)pParam; // ïðåîáðàçîâàíèå àðãóìåíòà ê óêàçàòåëþ íà îáúåêò âèäà
    CSimplexDoc* pDoc = pView->GetDocument();
    //  ASSERT_VALID(pDoc);
    pView->m_bWorking = true;
    int xmin=30, xmax=1030, ymin=30, ymax=1030;
    int morphX=(xmax-xmin)/5;
    int morphY=-morphX;
    CPen penlight(PS_SOLID, 1, RGB(230,230,230));
    CPen pendark(PS_SOLID, 2, RGB(25,25,25));
    CPen pengreen(PS_SOLID, 5, RGB(0,255,0));
    CPen penbluefat(PS_SOLID, 5, RGB(0,0,255));
    CPen penbluethin(PS_SOLID, 1, RGB(0,0,255));
    for (int i=0;i<pDoc->Iter;i++)
    if (pView->ViewCheck==1)
    {
    EnterCriticalSection(&pView->m_ClientDCLock);
    pView->m_pDC->SelectObject(pengreen);
    pView->m_pDC->MoveTo(pDoc->X[i][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i][0][1]*morphY+(ymax+ymin)/2);
    pView->m_pDC->LineTo(pDoc->X[i][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i][0][1]*morphY+(ymax+ymin)/2);

    pView->m_pDC->SelectObject(penlight);
    pView->m_pDC->LineTo(pDoc->X[i][1][0]*morphX+(xmax+xmin)/2, pDoc->X[i][1][1]*morphY+(ymax+ymin)/2);
    pView->m_pDC->LineTo(pDoc->X[i][2][0]*morphX+(xmax+xmin)/2, pDoc->X[i][2][1]*morphY+(ymax+ymin)/2);
    pView->m_pDC->LineTo(pDoc->X[i][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i][0][1]*morphY+(ymax+ymin)/2);

    pView->m_pDC->SelectObject(penbluefat);
    pView->m_pDC->MoveTo(pDoc->X[i][pDoc->MaxF[i]][0]*morphX+(xmax+xmin)/2, pDoc->X[i][pDoc->MaxF[i]][1]*morphY+(ymax+ymin)/2);
    pView->m_pDC->LineTo(pDoc->X[i][pDoc->MaxF[i]][0]*morphX+(xmax+xmin)/2, pDoc->X[i][pDoc->MaxF[i]][1]*morphY+(ymax+ymin)/2);
    pView->m_pDC->SelectObject(penbluethin);
    pView->m_pDC->LineTo(pDoc->X[i+1][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i+1][0][1]*morphY+(ymax+ymin)/2);    
    pView->m_pDC->SelectObject(penbluefat);
    pView->m_pDC->LineTo(pDoc->X[i+1][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i+1][0][1]*morphY+(ymax+ymin)/2);
    GdiFlush();
    LeaveCriticalSection(&pView->m_ClientDCLock);

    Sleep(1000);
    }
    pView->m_pDC->SelectObject(pendark);
    for (i=0;i<pDoc->Iter-1;i++)
    if (pView->ViewCheck==1)
    {
    pView->m_pDC->MoveTo(pDoc->X[i][pDoc->MinF[i]][0]*morphX+(xmax+xmin)/2, pDoc->X[i][pDoc->MinF[i]][1]*morphY+(ymax+ymin)/2);
    pView->m_pDC->LineTo(pDoc->X[i+1][pDoc->MinF[i+1]][0]*morphX+(xmax+xmin)/2, pDoc->X[i+1][pDoc->MinF[i+1]][1]*morphY+(ymax+ymin)/2);
    }
    pView->m_bWorking = false;
    return 0;
    }

    void CSimplexView::OnDraw(CDC* pDC)
    {
    CSimplexDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    TEXTMETRIC Metric;
    pDC->GetTextMetrics(&Metric);
    CString str;
    CSize size;
    if (ViewCheck==1)
    {
    CPen pen(PS_SOLID, 1, RGB(0,0,0));
    pDC->SelectObject(pen);
    CSize NameSize;
    CString strName;
    CFont font;
    CFont* pOldFont = NULL; // óêàçàòåëü íà ðàíåå èñïîëüçóåìûé øðèôò
    //  int xmin[3]={30,30,560}, xmax[3]={530,530,1060}, ymin[3]={30,560,30}, ymax[3]={530,1060,530};
    int xmin[3]={30,30,30}, xmax[3]={1030,1030,1030}, ymin[3]={2090,1060,30}, ymax[3]={3090,2060,1030};
    int morphX=(xmax[1]-xmin[1])/5;
    int morphY=-morphX;
    if(font.CreateFontIndirect(&pDoc->m_logFont)) pOldFont=pDC->SelectObject(&font);

    //Ñèñòåìà êîîðäèíàò
    //îêíà     
    for (int i=0;i<3;i++)
    {
    pDC->MoveTo(xmin[i]-5,ymin[i]-5);
    pDC->LineTo(xmax[i]+5,ymin[i]-5);
    pDC->LineTo(xmax[i]+5,ymax[i]+5);
    pDC->LineTo(xmin[i]-5,ymax[i]+5);
    pDC->LineTo(xmin[i]-5,ymin[i]-5);
    pDC->MoveTo(xmin[i]-10,ymin[i]-10);
    pDC->LineTo(xmax[i]+10,ymin[i]-10);
    pDC->LineTo(xmax[i]+10,ymax[i]+10);
    pDC->LineTo(xmin[i]-10,ymax[i]+10);
    pDC->LineTo(xmin[i]-10,ymin[i]-10);
    }

    //îñè äëÿ òðàåêòîðèè
    i=2;
    pDC->MoveTo((xmax[i]+xmin[i])/2,ymin[i]);
    pDC->LineTo((xmax[i]+xmin[i])/2+3,ymin[i]+10);
    pDC->MoveTo((xmax[i]+xmin[i])/2,ymin[i]);
    pDC->LineTo((xmax[i]+xmin[i])/2-3,ymin[i]+10);
    pDC->MoveTo((xmax[i]+xmin[i])/2,ymin[i]);
    pDC->LineTo((xmax[i]+xmin[i])/2,ymax[i]);
    pDC->MoveTo(xmin[i],(ymax[i]+ymin[i])/2);
    pDC->LineTo(xmax[i],(ymax[i]+ymin[i])/2);
    pDC->LineTo(xmax[i]-10,(ymax[i]+ymin[i])/2+3);
    pDC->MoveTo(xmax[i],(ymax[i]+ymin[i])/2);
    pDC->LineTo(xmax[i]-10,(ymax[i]+ymin[i])/2-3);             
    //ðàçìåòêà äëÿ òðàåêòîðèè
    for (int j=-4;j<5;j++)
    {
    pDC->MoveTo((xmax[i]+xmin[i])/2+(morphX/2)*j,(ymax[i]+ymin[i])/2-2);
    pDC->LineTo((xmax[i]+xmin[i])/2+(morphX/2)*j,(ymax[i]+ymin[i])/2+3);
    str.Format("%.1f",j*0.5);
    pDC->TextOut((xmax[i]+xmin[i])/2+(morphX/2)*j-5,(ymax[i]+ymin[i])/2+10,str);
    }
    for (j=-4;j<5;j++)
    {
    pDC->MoveTo((xmax[i]+xmin[i])/2-2, (ymax[i]+ymin[i])/2+(morphY/2)*j);
    pDC->LineTo((xmax[i]+xmin[i])/2+3, (ymax[i]+ymin[i])/2+(morphY/2)*j);
    str.Format("%.1f",-j*0.5);
    pDC->TextOut((xmax[i]+xmin[i])/2+10,(ymax[i]+ymin[i])/2+(morphY/2)*j-5, str);
    }
    for (i=1;i>=0;i--)
    {
    //îñè äëÿ îñòàëüíûõ ãðàôèêîâ
    pDC->MoveTo(xmin[i],ymin[i]);
    pDC->LineTo(xmin[i]+3,ymin[i]+10);
    pDC->MoveTo(xmin[i],ymin[i]);
    pDC->LineTo(xmin[i]-3,ymin[i]+10);
    pDC->MoveTo(xmin[i],ymin[i]);
    pDC->LineTo(xmin[i],ymax[i]);
    pDC->LineTo(xmax[i],ymax[i]);
    pDC->LineTo(xmax[i]-10,ymax[i]+3);
    pDC->MoveTo(xmax[i],ymax[i]);
    pDC->LineTo(xmax[i]-10,ymax[i]-3);             
    //ðàçìåòêà äëÿ îñòàëüíûõ ãðàôèêîâ
    for (int j=0;j<10;j++)
    {
    pDC->MoveTo(xmin[i]+(morphX/2)*j,ymax[i]-2);
    pDC->LineTo(xmin[i]+(morphX/2)*j,ymax[i]+3);
    str.Format("%.1f",j*0.5);
    pDC->TextOut(xmin[i]+(morphX/2)*j-5,ymax[i]-20,str);
    }
    for (j=0;j<10;j++)
    {
    pDC->MoveTo(xmin[i]-2,ymax[i]+(morphY/2)*j);
    pDC->LineTo(xmin[i]+3,ymax[i]+(morphY/2)*j);
    str.Format("%.1f",-j*0.5);
    pDC->TextOut(xmin[i]+10,ymax[i]+(morphY/2)*j-5, str);
    }
    }
    //íàçâàíèÿ
    if (pOldFont != NULL) pDC->SelectObject(pOldFont);

    i=2;
    strName="Òðàåêòîðèÿ ïîèñêà";
    NameSize=pDC->GetTextExtent(strName);
    pDC->TextOut((xmax[i]+xmin[i]-NameSize.cx)/2,ymin[i]+30,strName);
    pDC->TextOut((xmax[i]+xmin[i])/2+10,ymin[i],"X2");
    pDC->TextOut(xmax[i]-15,(ymax[i]+ymin[i])/2-25, "X1");

    for (i=1; i>=0; i--)
    {
    if (i==0)
    strName="Ãðàôèê çíà÷åíèÿ ôóíêöèè ïî øàãàì";
    if (i==1)
    strName="Ãðàôèê ðàññòîÿíèÿ îò òåêóùåé òî÷êè äî òî÷êè îïòèìóìà";           
    NameSize=pDC->GetTextExtent(strName);
    pDC->TextOut((xmax[i]+xmin[i]-NameSize.cx)/2,ymin[i]+30,strName);
    pDC->TextOut(xmin[i]+10,ymin[i],"X2");
    pDC->TextOut(xmax[i]-15,ymax[i]-25, "X1");     
    }
    //////////////////////////////
    // ñîáñòâåííî ãðàôèêè
    CPen pengreen(PS_SOLID, 5, RGB(0,255,0));
    CPen penred(PS_SOLID, 5, RGB(255,0,0));

    pDC->SelectObject(penred);
    pDC->MoveTo(morphX+(xmax[2]+xmin[2])/2, morphY+(ymax[2]+ymin[2])/2);
    pDC->LineTo(morphX+(xmax[2]+xmin[2])/2, morphY+(ymax[2]+ymin[2])/2);

    pDC->SelectObject(pengreen);
    pDC->MoveTo(pDoc->XInst[0]*morphX+(xmax[2]+xmin[2])/2, pDoc->XInst[1]*morphY+(ymax[2]+ymin[2])/2);
    pDC->LineTo(pDoc->XInst[0]*morphX+(xmax[2]+xmin[2])/2, pDoc->XInst[1]*morphY+(ymax[2]+ymin[2])/2);

    size.cx= xmax[0]+30;
    size.cy= ymax[0]+10;
    }
    else
    {
    pDC->TextOut(0, 0, "Ôóíêöèÿ (x2 - x1^2 )^2 + (1 - x1 )^2");
    str="Íà÷àëüíàÿ òî÷êà ("+pDoc->Coord+')';
    pDC->TextOut(0, Metric.tmHeight, str);
    pDC->TextOut(0, 2*Metric.tmHeight, "Òåîðåòè÷åñêàÿ òî÷êà îïòèìóìà (1;1)");

    CString tmp;
    for (int k=0; k<pDoc->Iter; k++)
    {
    str.Format("%d",k+1);
    str="Ñèìïëåêñ "+str;
    pDC->TextOut(0,(4+6*k)*Metric.tmHeight, str);
    for (int i=0;i<3;i++)
    {
    tmp.Format("%d",i);
    str=" òî÷êå "+tmp+" (";
    for (int j=0;j<2;j++)
    {
    tmp.Format("%.3f",pDoc->X[k][i][j]);
    str+=tmp+';';
    }
    tmp.Format("%.3f",pDoc->Fx[k][i]);
    str=str.Left(str.GetLength()-1);
    str+=") ôóíêöèÿ ðàâíà "+tmp;
    pDC->TextOut(0,(5+i+6*k)*Metric.tmHeight, str);
    }
    tmp.Format("%d",pDoc->MaxF[k]);
    str="Ìàêñèìàëüíîå çíà÷åíèå ôóíêöèè íàáëþäàëîñü â òî÷êå "+tmp;
    pDC->TextOut(0,(8+6*k)*Metric.tmHeight, str);
    }
    size.cx= 500;
    size.cy= (4+6*pDoc->Iter)*Metric.tmHeight;
    }
    SetScrollSizes(MM_TEXT,size);
    }

    void CSimplexView::OnInitialUpdate()
    {
    CScrollView::OnInitialUpdate();

    CSize sizeTotal;
    // TODO: calculate the total size of this view
    sizeTotal.cx = sizeTotal.cy = 100;
    SetScrollSizes(MM_TEXT, sizeTotal);
    }

    /////////////////////////////////////////////////////////////////////////////
    // CSimplexView printing

    BOOL CSimplexView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    // default preparation
    return DoPreparePrinting(pInfo);
    }

    void CSimplexView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    // TODO: add extra initialization before printing
    }

    void CSimplexView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    // TODO: add cleanup after printing
    }

    /////////////////////////////////////////////////////////////////////////////
    // CSimplexView diagnostics

    #ifdef _DEBUG
    void CSimplexView::AssertValid() const
    {
    CScrollView::AssertValid();
    }

    void CSimplexView::Dump(CDumpContext& dc) const
    {
    CScrollView::Dump(dc);
    }

    CSimplexDoc* CSimplexView::GetDocument() // non-debug version is inline
    {
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSimplexDoc)));
    return (CSimplexDoc*)m_pDocument;
    }
    #endif //_DEBUG

    /////////////////////////////////////////////////////////////////////////////
    // CSimplexView message handlers

    void CSimplexView::OnViewGraph()
    {
    // TODO: Add your command handler code here
    if (ViewCheck==0)
    {
    Invalidate ();
    ViewCheck=1;
    }
    }

    void CSimplexView::OnViewTable()
    {
    // TODO: Add your command handler code here
    if (ViewCheck==1)
    {
    Invalidate ();
    ViewCheck=0;
    }
    }

    int CSimplexView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CScrollView::OnCreate(lpCreateStruct) == -1)
    return -1;

    // TODO: Add your specialized creation code here
    m_pDC = new CClientDC(this);    // ïîëó÷åíèå óêàçàòåëÿ íà êîíòåêñò îêíà
    return 0;
    }

    void CSimplexView::OnDestroy()
    {

    // TODO: Add your message handler code here
    m_bWorking=false;
    //  Sleep(m_nThreadCounter*20); // çàñíóòü íà 20 ìèëëèñåêóíä äëÿ êàæäîãî ïîòîêà
    //  m_nThreadCounter=0;
    delete m_pDC;
    m_pDC = 0;
    CView::OnDestroy();

    }

    void CSimplexView::OnUpdateViewSearchprocess(CCmdUI* pCmdUI)
    {
    // TODO: Add your command update UI handler code here
    if (ViewCheck==0 || m_bWorking==true)
    pCmdUI->Enable(false);
    else
    pCmdUI->Enable(true);

    }

    void CSimplexView::OnViewSearchprocess()
    {
    // TODO: Add your command handler code here
    Invalidate ();
    AfxBeginThread(SearchThread, this, THREAD_PRIORITY_IDLE);
    //  m_nThreadCounter++;
    }
    PS. Visual C++ 6.0
     
  2. gamecreator

    gamecreator Гость

    абсолютная координата = относительная координата + сдвиг по оси
    сдвиг по оси изменяешь при прокрутке.
    относительная координата - координата точки на экране
     
  3. OberonTSM

    OberonTSM Гость

    Спасибо... только как получить значение сдвига при прокрутке? если это знать думаю получится)
    Но всё таки хотелось бы понять как эту проблему решить с контекстом устройства... наверняка же от этого зависит... хотя... я не особо разбираюсь, может ерунду говорю.
     
  4. OberonTSM

    OberonTSM Гость

    Получилось!!! спасибо огромное!
    только
    абсолютная координата = относительная координата + сдвиг по оси это неправильно
    относительная координата = абсолютная координата + сдвиг по оси

    Теперь интересует как сделать так, чтобы рисунок не обнулялся
     
  5. Azrael

    Azrael Гость

    Для: OberonTSM

    рекомендую рисовать всё в back-буффер, который может быть и больше экрана, а на onShow вешать обработку копирования нужной области из back-буффера, заодно и от мерцания избавитесь.
     
  6. OberonTSM

    OberonTSM Гость

    Спасибо! надо будет как нибудь попробовать!
     
Загрузка...
Похожие Темы - Mfc Координаты Scroll
  1. PetrovVA
    Ответов:
    3
    Просмотров:
    1.720
  2. harimambura
    Ответов:
    0
    Просмотров:
    1.302
  3. Antonim
    Ответов:
    1
    Просмотров:
    1.237
  4. Antonim
    Ответов:
    4
    Просмотров:
    1.815
  5. ezus
    Ответов:
    4
    Просмотров:
    4.688
Статус темы:
Закрыта.

Поделиться этой страницей