home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
mfc
/
advanced
/
dllhusk
/
testdll2.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-03-26
|
7KB
|
232 lines
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "resource.h" // main symbols
#include "testres2.h" // symbols unique to this DLL
#include "testdll2.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// Initialization of MFC Extension DLL
#include "afxdllx.h" // standard MFC Extension DLL routines
static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// Extension DLL one-time initialization - do not allocate memory here,
// use the TRACE or ASSERT macros or call MessageBox
if (!AfxInitExtensionModule(extensionDLL, hInstance))
return 0;
// Other initialization could be done here, as long as
// it doesn't result in direct or indirect calls to AfxGetApp.
// This extension DLL doesn't need to access the app object
// but to be consistent with testdll1.dll, this DLL requires
// explicit initialization as well (see below).
// This allows for greater flexibility later in development.
}
return 1; // ok
}
// Exported DLL initialization is run in context of running application
extern "C" void WINAPI InitTestDLL2()
{
// create a new CDynLinkLibrary for this app
new CDynLinkLibrary(extensionDLL);
// nothing more to do
}
/////////////////////////////////////////////////////////////////////////////
// class CListOutputFrame
IMPLEMENT_DYNAMIC(CListOutputFrame, CMDIChildWnd)
BEGIN_MESSAGE_MAP(CListOutputFrame, CMDIChildWnd)
//{{AFX_MSG_MAP(CListOutputFrame)
ON_WM_CREATE()
ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CListOutputFrame::CListOutputFrame()
{
m_ppThis = NULL; // backpointer
// do nothing now (two-phase create)
}
CListOutputFrame::~CListOutputFrame()
{
// clear backpointer
if (m_ppThis != NULL)
{
ASSERT(*m_ppThis == this);
*m_ppThis = NULL;
}
}
BOOL CListOutputFrame::Create(LPCTSTR lpszWindowName,
DWORD dwStyle, const RECT& rect, CMDIFrameWnd* pParentWnd)
{
// we want to load a specific menu from this DLL
HINSTANCE hInstOld = AfxGetResourceHandle();
AfxSetResourceHandle(extensionDLL.hModule);
if (!m_menu.LoadMenu(IDR_LISTOUTPUT))
{
// restore the old resource chain and return error
AfxSetResourceHandle(hInstOld);
return FALSE;
}
AfxSetResourceHandle(hInstOld); // restore the old resource chain
// when the list output frame window is active, use this menu
m_hMenuShared = m_menu.m_hMenu;
// create the CMDIChildWnd, listbox created in OnCreate
return CMDIChildWnd::Create(NULL, lpszWindowName,
dwStyle, rect, pParentWnd);
}
int CListOutputFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// create dialog bar at top of the frame window (it is a toolbar)
if (!m_dlgBar.Create(this, IDD_DIALOGBAR1, WS_CHILD|CBRS_TOP,
AFX_IDW_TOOLBAR))
{
TRACE(_T("Failed to create toolbar for CListOutputFrame\n"));
return -1;
}
// create listbox as main pane (will fill rest of frame window)
if (!m_listBox.Create(WS_CHILD | WS_VISIBLE|
LBS_NOTIFY | LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | LBS_DISABLENOSCROLL | WS_BORDER,
CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST))
{
TRACE(_T("Failed to create listbox for CListOutputFrame\n"));
return -1;
}
m_listBox.SetFont(m_dlgBar.GetFont());
ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_DRAWFRAME);
m_listBox.ModifyStyle(0, WS_EX_CLIENTEDGE, SWP_DRAWFRAME);
return 0; // creation ok
}
void CListOutputFrame::Clear()
{
ASSERT(m_listBox.m_hWnd != NULL); // must be created
m_listBox.ResetContent();
}
void CListOutputFrame::AddString(LPCTSTR lpszItem)
{
ASSERT(m_listBox.m_hWnd != NULL); // must be created
int nIndex;
if ((nIndex = m_listBox.AddString(lpszItem)) < 0)
AfxThrowMemoryException();
m_listBox.SetCurSel(nIndex); // make last line visible
}
/////////////////////////////////////////////////////////////////////////////
// Edit commands
void CListOutputFrame::OnEditClear()
{
Clear();
}
void CListOutputFrame::OnEditCut()
{
OnEditCopy();
Clear();
}
void CListOutputFrame::OnEditCopy()
{
if (!OpenClipboard())
{
AfxMessageBox(_T("Failed to open clipboard"));
return;
}
if (!::EmptyClipboard())
{
AfxMessageBox(_T("Failed to empty clipboard"));
::CloseClipboard();
return;
}
// copy the current listbox contents to the clipboard as text
HGLOBAL hTextData = GetTextData();
if (hTextData == NULL ||
#ifndef _UNICODE
::SetClipboardData(CF_TEXT, hTextData) == NULL)
#else
::SetClipboardData(CF_UNICODETEXT, hTextData) == NULL)
#endif
{
AfxMessageBox(_T("Failed to set clipboard data"));
::CloseClipboard();
return;
}
if (!::CloseClipboard())
AfxMessageBox(_T("Failed to close clipboard"));
}
HGLOBAL CListOutputFrame::GetTextData()
{
// first find out how much space we need
int nLines = m_listBox.GetCount();
long cbTotal = 0;
for (int i = 0; i < nLines; i++)
cbTotal += m_listBox.GetTextLen(i) + 2; // CR/LF for each line
cbTotal += 1; // for end '\0'
// allocate a (shared) global memory block for the data
HGLOBAL hData = ::GlobalAlloc(GMEM_DDESHARE, cbTotal*sizeof(TCHAR));
if (hData == NULL)
return NULL; // NULL for memory failure
// now copy the strings, terminate each with CR/LF
LPTSTR lpOut = (LPTSTR)::GlobalLock(hData);
ASSERT(lpOut != NULL);
for (i = 0; i < nLines; i++)
{
m_listBox.GetText(i, lpOut);
lpOut += lstrlen(lpOut)*sizeof(TCHAR); // skip new string
*lpOut++ = 0xD; // CR
*lpOut++ = 0xA; // LF
}
*lpOut = '\0';
ASSERT(lpOut + 1 == (LPCTSTR)GlobalLock(hData) + cbTotal);
return hData;
}
/////////////////////////////////////////////////////////////////////////////