Vorschau in einem eigenem C++ (Kind-)Fenster verwenden

Gilt ab List & Label 24

Die Vorschau von List & Label steht prinzipiell in einem eigenen modalen Fenster zur Verfügung. Oft möchte man diese jedoch gerne in einem Fenster der eigenen Applikation anzeigen lassen. Für .NET gibt es hierzu bereits ein gesondertes Control dafür - siehe die Klasse ListLabelPreviewControl

Um nun die Vorschau auch in einem eigenen Fenster darstellen zu können, sind folgende Schritte notwendig. Die Beispiel-Codes basieren auf Visual C++ mit MFC-Klassen. Doch das Prinzip und die Vorgehensweise sollte auch auf andere Mechanismen für unmanaged Code übertragbar sein. Voraussetzung für eine eigene Umsetzung sind:

  • der Umgang mit Windows Fensterhandles
  • die Erzeugung neuer Fenster
  • das Senden von Fensternachrichten
  • der Umgang mit Callback-Routinen (optional)


1. Zunächst muss das für die Vorschau verantwortliche Modul von List & Label geladen werden. Für x86-Anwendungen wird das Modul cmls??.dll benötigt und für x64-Anwendungen cxls??.dll. Für das Laden stehen die beiden Möglichkeiten dynamisch oder statisch zur Verfügung.

dynamisch:

#include "cmbtls??.hx"
// ...

// load LS module/dll
LS??xLoad();

// do some stuff...

// unload LS module/dll
LS??xUnload()


statisch:
Fügen Sie eine zusätzliche Abhängigkeit im Projekt auf die Bibliothek cmls??.lib (x86) oder cxls??.lib (x64) hinzu und ergänzen Sie den folgenden Code:

#include "cmbtls??.h"
// ...

// load LS module/dll
LS??Load();

// do some stuff...

// unload LS module/dll
LS??Unload()


2. Um nun die Vorschau in einem eigenen Fenster zu hosten, muss hierzu entsprechend ein Fenster bzw. Control erstellt werden. Das Fensterhandle ist die Basis für die weitere Verwendung zur Ansteuerung der Vorschau:

CRect rcClient;
GetClientRect(rcClient);

DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

/*HWND*/ m_hWndLLPreviewCtrl = CreateWindow(
							::LsGetViewerControlClassName(), // e.g. "LlStgsysViewerControl??W"
							_T(""),
							dwStyle,
							0, 0, rcClient.Width(), rcClient.Height(),
							GetSafeHwnd(),
							(HMENU)1,
							AfxGetInstanceHandle(),
							NULL
							);
ASSERT(m_hWndLLPreviewCtrl != NULL);


3. Mit Hilfe von diversen Optionen können Eigenschaften für die Vorschau bestimmt werden. Mögliche Werte können dem jeweiligen Header-File entnommen werden. Um bspw. die Toolbar der Vorschau nicht anzuzeigen kann folgende Nachricht an das Fensterhandle gesendet werden:

::SendMessage(m_hWndLLPreviewCtrl, LS_VIEWERCONTROL_SET_OPTION, LS_OPTION_TOOLBAR, 0 /* 0 means no toolbar */);


4. Um nun auch auf Nachrichten oder Events der Vorschau selbst reagieren zu können wie bspw. es wurde ein bestimmter Button in der Toolbar geklickt (siehe LS_VIEWERCONTROL_NTFY_BTNPRESSED), es soll eine eigene Fortschrittsanzeige verwendet werden (siehe LS_VIEWERCONTROL_NTFY_PROGRESS) usw., kann ein sogenannter Callback für das neue Fenster der Vorschau angemeldet werden:

// attach Callback to preview with used defined data
::SendMessage(m_hWndLLPreviewCtrl, LS_VIEWERCONTROL_SET_OPTION, LS_OPTION_USERDATA, (LPARAM)this);
::SendMessage(m_hWndLLPreviewCtrl, LS_VIEWERCONTROL_SET_NTFYCALLBACK, NULL, (LPARAM)CBNtfyViewerCallback);
// ...
/*static*/ LRESULT CALLBACK MyPreviewClass::CBNtfyViewerCallback(UINT nMsg, WPARAM wParam,LPARAM lUserParam)
{
	MyPreviewClass* pThis = (MyPreviewClass*)lUserParam;
	return(pThis->NtfyViewerCallback(nMsg, wParam));
}
// ...
LRESULT CALLBACK MyPreviewClass::NtfyViewerCallback(UINT nMsg, LPARAM lParam)
{
	switch(nMsg)
	{
		case LS_VIEWERCONTROL_NTFY_BTNPRESSED:
		{
			// lParam contains the control ID - see also MenuID.txt
			// ...
		}
		break;

		case LS_VIEWERCONTROL_NTFY_PROGRESS:
		{
			// lParam = percentage (-1=finished). 
			// return: 1 if internal progress bar shall be suppressed
			// ...
			
			return 1;
        }
		break;
	}
	
	return (0);
}


5. Damit nun der Druck in das neue eigene Vorschaufenster durchgeführt werden kann, muss dies dem Druckjob von List & Label noch mitgteilt werden:

// attach preview window
::LlAssociatePreviewControl(m_hJob, m_hWndLLPreviewCtrl, 1);

// execute print/export...

// detach preview window
::LlAssociatePreviewControl(m_hJob, NULL, 1);

IDKBTD001372 KBTD001372