Print preview in explore

Intrebari legate de programarea cu biblioteci precum MFC, ATL, WTL si GDI+.
mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 29 Aug 2014, 13:48

M-am intors la gridul in printpreview, insa cu o rezolvare mult mai simpla: in frame-ul print-preview, as vrea sa creez un treeview (in stanga) pe care sa pun tot ce tine de print/printpreview.
Ok, CGridCtrl are o rezolvare foarte simpla pentru printpreview: ascunde frame-ul principal, si creeaza unul noul:

Code: Select all

	CFrameWnd* pOldFrame=(CFrameWnd*)AfxGetThread()->m_pMainWnd;
	pOldFrame->ShowWindow(SW_HIDE); //added by eric

	if(! m_pTemplate)
	{
		m_pTemplate = new CSingleDocTemplate(
			IDR_MAINFRAME,
			NULL,
			RUNTIME_CLASS(CFrameWnd),
			RUNTIME_CLASS(CViewPrintPreview));
		AfxGetApp()->AddDocTemplate(m_pTemplate);
	}

	CFrameWnd* pFrameWnd = m_pTemplate->CreateNewFrame(NULL, NULL);
	m_bPrintPreview = TRUE;

	m_pTemplate->InitialUpdateFrame(pFrameWnd, NULL, FALSE);

	CViewPrintPreview* pView = (CViewPrintPreview*)pFrameWnd->GetActiveView();
	pView->m_pCtrl = this;
	pView->m_pOldFrame = pOldFrame;

	AfxGetApp()->m_pMainWnd = pFrameWnd;
	pFrameWnd->SetWindowText(_T("Grid Print Preview"));
	pFrameWnd->ShowWindow(SW_SHOWMAXIMIZED);
	pView->OnFilePrintPreview();
simplu, si m-am gandit ca daca in loc de CFrameWnd, pun o clasa derivata, in care sa am pus un splitter, cu 2 view-uri: left view cu CTreeView, si right view cu printpreview:

Code: Select all

	CFrameWnd* pOldFrame = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
	pOldFrame->ShowWindow(SW_HIDE); //added by eric

	if(NULL == m_pTemplate)
	{
		m_pTemplate = new CSingleDocTemplate(
			IDR_MAINFRAME,
			NULL,
			RUNTIME_CLASS(CRPPMainFrame),
			RUNTIME_CLASS(CRPPLeftView));
		AfxGetApp()->AddDocTemplate(m_pTemplate);
	}

	CRPPMainFrame* pFrameWnd = (CRPPMainFrame*)m_pTemplate->CreateNewFrame(NULL, NULL);
	m_bPrintPreview = TRUE;

	m_pTemplate->InitialUpdateFrame(pFrameWnd, NULL, FALSE);

	CReportPrintPreview* pView = (CReportPrintPreview*)pFrameWnd->GetRightPane();
	pView->m_pCtrl = this;
	pView->m_pOldFrame = pOldFrame;

	AfxGetApp()->m_pMainWnd = pFrameWnd;
	pFrameWnd->SetWindowText(_T("Tree Print Preview"));
	pFrameWnd->ShowWindow(SW_SHOWMAXIMIZED);
	pView->OnFilePrintPreview();
toate bune si frumoase ... doar ca left-view-ul nu apare ... de ce ? Ce mai trebuie sa fac, pentru a avea ambele view-uri din splitter disponibile ?
Codul din CRPPMainFrame e de asemenea simplu:

Code: Select all

BOOL CRPPMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,	CCreateContext* pContext)
{
	// create splitter window
	if(! m_wndSplitter.CreateStatic(this, 1, 2))
		return FALSE;

	if(! m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CRPPLeftView), CSize(100, 100), pContext) || 
		! m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CReportPrintPreview), CSize(100, 100), pContext))
	{
		m_wndSplitter.DestroyWindow();
		return FALSE;
	}

	return TRUE;
}
trece pe acolo, doar ca desi le creeaza, nu apar la run-time ... de ce ?
Atasez si un mic demo, pentru exemplificare ...
Attachments
TestExplore.zip
(244.41 KiB) Downloaded 285 times



mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 29 Aug 2014, 13:50

Am incercat sa pun in:

Code: Select all

      m_pTemplate = new CSingleDocTemplate(
         IDR_MAINFRAME,
         NULL,
         RUNTIME_CLASS(CFrameWnd),
         RUNTIME_CLASS(CViewPrintPreview));
      AfxGetApp()->AddDocTemplate(m_pTemplate);
si o clasa document, nu merge ... As fi recunoscator pentru orice ajutor.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Print preview in explore

Post by Ovidiu Cucu » 30 Aug 2014, 19:30

Pai, nu se vad din doua motive:
  1. fereastra de print preview este in asa fel facuta incat ocupa impreuna cu dialogbar-ul toata zona client a frame-ului parinte (subliniez frame-ul parinte si nu un pane dintr-un splitter);
  2. in modul print preview, framework-ul ascunde ceilalt copilasi ai frame-ului, in cazul mostru acel splitter care tine view-urile initiale.
Nu vad o cale usoara de a baga preview-ul intr-un pane de splitter, folosind ceva derivat din CPreviewView.
Asa ca, zic eu, mai bine iti faci de la zero clasa ta de preview, derivata direct din CView.
E un pic de munca insa asta e...
Ca sa comuti view-urile dintr-un pane, poti face ceva de genul:

Code: Select all

void CChildFrame::_ChagePaneView(int nRow, int nCol, SIZE sizeInit, CRuntimeClass* pClass)
{
    CWnd* pwndPane = m_wndSplitter.GetPane(nRow, nCol);
    ASSERT_KINDOF(CView, pwndPane);
    if(! pwndPane->IsKindOf(pClass))
    {
        m_wndSplitter.DeleteView(nRow, nCol);
        VERIFY(m_wndSplitter.CreateView(nRow, nCol, pClass, sizeInit, NULL));
        m_wndSplitter.RecalcLayout();
    }
}


void CChildFrame::OnSetPrintPreviewView()
{
    _ChagePaneView(0, 1, CSize(100, 100), RUNTIME_CLASS(CPrintPreviewView));
}


void CChildFrame::OnSetInitialView()
{
    _ChagePaneView(0, 1, CSize(100, 100), RUNTIME_CLASS(CInitialView));
}
Asta a fost doar ca exemplu, rapid. Mai bine derivezi din CSplitterWnd si bagi acolo o metoda publica ChagePaneView.

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 01 Sep 2014, 09:20

Sper ca am inteles ce trebuie facut, ma apuc de lucru, sa vad ce iese ...

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 02 Sep 2014, 13:54

Stiam ca o sa cada strachini de pe stelaja ...
Am creat o clasa CPrintView, derivata din CScrollView (si CPreviewView e derivata din CScrollView, nu din CView). Si am pus-o in framework-ul creeat de print-ul gridului ... ok, desi nu am nimic inca pe acest CPrintView, se creeaza frumos aceasta fereastra, cu tot cu tree-ul din stanga ... insa raman cateva probleme de rezolvat:

1. Tree-ul din stanga nu se initializeaza; nu se apeleaza CRPPLeftView::OnInitialUpdate().
2. Nu stiu unde sa fac curatenie cand distrug CPrintView-ul ... in vechea implementare, curatenia se face in CPrintPreview::OnEndPrintPreview, dar ca sa se apeleze aceasta metoda, ar trebui sa pornesc totul cu

Code: Select all

void CPrintPreview::OnFilePrintPreview()
{
	CView::OnFilePrintPreview();
}
dar atunci am tot printpreview-ul pe tot frame-ul, si ma intorc de unde am pornit.

Am incercat sa fac curat in CPrintView::OnDestroy(), dar am obtinut un memory leaks de toata frumusetea ...

Atasez proiectul in stadiul acesta, daca cineva are timpul (si rabdarea, sau curiozitatea) sa se uite la el ... intre timp, mai pilesc pe el, sa vad ce iese ...
Attachments
TestExplore.zip
(246.03 KiB) Downloaded 296 times

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 02 Sep 2014, 18:06

De reconstruit CPrintView ma gandescc ca nu ar fi asa greu, cata vreme ma pot "inspira" din sursa CPreviewView ... doar ca inca nu pot face asta fiindca nu merge cum trebuie CPrintView aproape fara nimica in ea ...

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 03 Sep 2014, 15:48

Cand zic de facut curat in CPrintPreview, ma refer la codul care in vechea implementare distrugea frame-ul printpreview-ului, si facea restore frame-ului original, cod care, asa cum am zis, era pus in CPrintPreview::OnEndPrintPreview:

Code: Select all

void CPrintPreview::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView) 
{
	CView::OnEndPrintPreview(pDC, pInfo, point, pView);
	// Show the original frame
	m_pOldFrame->ShowWindow(SW_SHOW);
	// Restore main frame pointer
	AfxGetApp()->m_pMainWnd = m_pOldFrame;
	m_pCtrl->m_bPrintPreview = FALSE;
	// Kill parent frame and itself
	GetParentFrame()->DestroyWindow();
	GetParentFrame()->ShowWindow(SW_HIDE);
}
evident ca incercarea de a pune acest cod [bine, fara ultimele 2 linii de cod], in CPrintPreview::OnDestroy, a rezultat intr-un esec ... rasunator ...

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 15 Sep 2014, 11:24

Am modificat arhitectura aplicatiei dupa postul http://www.codexpert.ro//forum/viewtopi ... =15#p16380.

Code: Select all

void CChildFrame::ChagePaneView(int nRow, int nCol, SIZE sizeInit, CRuntimeClass* pClass)
{
	CWnd* pWndPane = m_wndSplitter.GetPane(nRow, nCol);
	ASSERT_KINDOF(CView, pWndPane);
	if(! pWndPane->IsKindOf(pClass))
	{
		m_wndSplitter.DeleteView(nRow, nCol);
		VERIFY(m_wndSplitter.CreateView(nRow, nCol, pClass, sizeInit, NULL));
		m_wndSplitter.RecalcLayout();
	}
}

void CChildFrame::OnSetInitialView()
{
	ChagePaneView(0, 1, CSize(100, 100), RUNTIME_CLASS(CTestExploreView));
}

void CChildFrame::OnSetPrintPreviewView()
{
	ChagePaneView(0, 1, CSize(100, 100), RUNTIME_CLASS(CPrintPreview));
}
ramane doar de construit CPrintPreview, dupa modelul CPreviewView ... insa pentru asta ar fi nevoie de CPrintInfo* m_pPreviewInfo care nu se poate afla decat in momentul printarii ... numai daca comut view-ul in partea dreapta a explorerului, nu pot ajunge la CPrintInfo ...

P.S. In proiectul atasat, CPrintPreview este derivat din CScrollView, nu din CPreviewView.
Attachments
TestExplore.zip
(242.69 KiB) Downloaded 270 times

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 16 Sep 2014, 16:37

Cred ca sant in situatia de la inceput, cand pot schimba view-ul din explorer, cu un view derivat din CView (de fapt din CScrollView), unde ar trebui sa reconstruiesc print-preview-ul, dar nu am CPrintInfo, fara de care nu am informatii despre print ...

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Print preview in explore

Post by Ovidiu Cucu » 16 Sep 2014, 17:02

Chestia cu CPrintInfo n-ar fi o asa mare problema. I-am putea gasi noi un loc unde sa fie instantiat, apoi umplut cu ce trebuie si in cele din urma de "mimat" tot flow-ul pentru print (preview) la fel ca la alte view-uri din framework.
Problema naspa este ca atunci cand comuti pe preview, view-ul initial se distruge, distrugandu-se in acelasi timp si controlul de grid pe care-l contine.
CGridCtrl contine toate datele in el asa ca, odata distrus, nu mai stii ce sa afisezi in preview.

Daca s-ar putea sa scoti toate atributele in afara CGridCtrl atunci le-ai putea pastra in clasa document.
Sau te-ai putea gandi cum sa implementezi preview-ul direct in CGridCtrl si atunci nu mai trebuie sa faci switch intre view-uri (oricum nu asa cum e facut acum).
Sau te-ai putea apuca voiniceste sa faci propria ta clasa de grid view.

Cam la toate-i munca de Sisif. :)

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 17 Sep 2014, 10:40

Multumesc mult pentru raspuns, pentru mine conteaza mult orice indrumare ... nu-i bai ca e mult de munca, o sa fac ce este necesar ...
Sau te-ai putea apuca voiniceste sa faci propria ta clasa de grid view
Cred ca in acest caz este cel mai mult de lucru ...
Daca s-ar putea sa scoti toate atributele in afara CGridCtrl
Asta mi se pare cea mai usoara solutie ... dar nu prea inteleg ce este de facut ... eventual, in cazul print-preview, fac mai intai o copie a CGridCtrl-ului in clasa document, ca mai apoi s-o accesez in print-preview ...

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Print preview in explore

Post by Ovidiu Cucu » 18 Sep 2014, 10:16

Pai sa tot fie mai bine de doua luni de cand tot carpim opera de tinerete a lui Chris.
O fi el un grid minunat insa a ajuns ca un pom de Craciun, atat de incarcat incat daca mai agati un globulet se rupe sau rastoarna. :)

Eu as face cam asa, de la zero:
  • un control cu mesaje si notificari dupa modelul controalelor Windows built-in (ca de exemplu SysListView32);
  • peste el, un wrapper C++ derivat din CWnd, ca de exemplu CListCtrl;
  • o clasa derivata din CCtrlView gen CListView;
  • eventual si un OCX, ca sa se bucure si programatorii VB. :)


Ar fi ceva de trenspirat insa putem face ce vrea muschii nostri si sa punem capat la carpeli prin ce-au facut altii.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Print preview in explore

Post by Ovidiu Cucu » 18 Sep 2014, 11:19

...daca n-as avea alta treaba de facut, in maxim doua luni ar fi gata. :)

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 18 Sep 2014, 12:15

Ahh ... nu ma gandeam ca e atat de lucru ... sa construiesc alt grid, asta intradevar e mult de lucru, fiindca deja CGridCtrl are mod de lucru virtual (ceea ce imi trebuie si mie in viitorul nu prea indepartat), si plus alte o mie si una de lucruri ... de aia as fi adaptat ce este deja, doar sa am in print-preview-ul gridului, un alt control decat dialogbar-ul standard al printpreview-ului ... plus ca CGridCtrl asta e "rodat" de alti programatori, indeajuns cat sa fie sigur in functionare ... daca l-as face eu de la zero ... n-as fi asa sigur :D

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Print preview in explore

Post by mesajflaviu » 18 Sep 2014, 12:17

Si ma gandesc la ceva: cum as putea "adapta" un printpreview in CGridCtrl-ul existent ? Caci noua solutie ar trebui sa se ocupe si de asta ... atunci nu mai bine pun in cel existent acel print-preview ?

Post Reply