The following steps are necessary to display the preview in a separate window. The example codes are based on Visual C++ with MFC classes. But the principle and the procedure should also be transferable to other mechanisms for unmanaged code. Prerequisites for an own implementation are:
- the handling with Windows window handles
- the creating of new windows
- the sending of window messages
- the handling with callbacks (optional)
dynamic:
#include "cmbtls??.hx"
// ...
// load LS module/dll
LS??xLoad();
// do some stuff...
// unload LS module/dll
LS??xUnload()
static:
Add an additional dependency in the project to the cmls??.lib (x86) or cxls??.lib (x64) library and add the following code:
#include "cmbtls??.h"
// ...
// load LS module/dll
LS??Load();
// do some stuff...
// unload LS module/dll
LS??Unload()
2. In order to host the preview in a separate window, a window or control must be created accordingly. The window handle is the basis for further use to control the preview:
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. With the help of various options, properties can be determined for the preview. Possible values can be taken from the header file. In order not to display the toolbar of the preview, the following message can be sent to the window handle:
::SendMessage(m_hWndLLPreviewCtrl, LS_VIEWERCONTROL_SET_OPTION, LS_OPTION_TOOLBAR, 0 /* 0 means no toolbar */);
4. In order to be able to react to messages or events of the preview itself, e.g. a certain button in the toolbar was clicked (see LS_VIEWERCONTROL_NTFY_BTNPRESSED), an own progress indicator is to be used (see LS_VIEWERCONTROL_NTFY_PROGRESS) etc., a callback can be registered for the new preview window:
// 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. In order to be able to print in the new preview window, the print job of List & Label has to be informed:
// attach preview window
::LlAssociatePreviewControl(m_hJob, m_hWndLLPreviewCtrl, 1);
// execute print/export...
// detach preview window
::LlAssociatePreviewControl(m_hJob, NULL, 1);