// BeBeCtl.cpp : Implementation of the CBeBeCtrl ActiveX Control class. #include "stdafx.h" #include "BeBe.h" #include "BeBeCtl.h" #include "BeBePpg.h" #include #include #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif /////////////////////////////////////////////////////////////////////// HISTORY CHistory::Undo() { long nSize = m_undo.GetSize(); if (nSize <= 0) { HISTORY temp; temp.ptFill.x = -1; temp.ptFill.y = -1; return temp; } HISTORY temp = m_undo[nSize - 1]; m_redo.Add(temp); m_undo.RemoveAt(nSize - 1); return temp; } HISTORY CHistory::Redo() { long nSize = m_redo.GetSize(); if (nSize <= 0) { HISTORY temp; temp.ptFill.x = -1; temp.ptFill.y = -1; return temp; } HISTORY temp = m_redo[nSize - 1]; m_undo.Add(temp); m_redo.RemoveAt(nSize - 1); return temp; } BOOL CHistory::UndoState() { if (m_undo.GetSize() > 0) return TRUE; return FALSE; } BOOL CHistory::RedoState() { if (m_redo.GetSize() > 0) return TRUE; return FALSE; } void CHistory::NewFill(HISTORY history) { m_undo.Add(history); m_redo.RemoveAll(); } void CHistory::Clear() { m_undo.RemoveAll(); m_redo.RemoveAll(); } /////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNCREATE(CBeBeCtrl, COleControl) ///////////////////////////////////////////////////////////////////////////// // Message map BEGIN_MESSAGE_MAP(CBeBeCtrl, COleControl) //{{AFX_MSG_MAP(CBeBeCtrl) ON_WM_CREATE() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_SETCURSOR() //}}AFX_MSG_MAP ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Dispatch map BEGIN_DISPATCH_MAP(CBeBeCtrl, COleControl) //{{AFX_DISPATCH_MAP(CBeBeCtrl) DISP_FUNCTION(CBeBeCtrl, "SetImageURL", SetImageURL, VT_EMPTY, VTS_BSTR) //}}AFX_DISPATCH_MAP DISP_FUNCTION_ID(CBeBeCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE) END_DISPATCH_MAP() ///////////////////////////////////////////////////////////////////////////// // Event map BEGIN_EVENT_MAP(CBeBeCtrl, COleControl) //{{AFX_EVENT_MAP(CBeBeCtrl) EVENT_CUSTOM("OnInitImage", FireOnInitImage, VTS_NONE) //}}AFX_EVENT_MAP END_EVENT_MAP() ///////////////////////////////////////////////////////////////////////////// // Property pages // TODO: Add more property pages as needed. Remember to increase the count! BEGIN_PROPPAGEIDS(CBeBeCtrl, 1) PROPPAGEID(CBeBePropPage::guid) END_PROPPAGEIDS(CBeBeCtrl) ///////////////////////////////////////////////////////////////////////////// // Initialize class factory and guid IMPLEMENT_OLECREATE_EX(CBeBeCtrl, "BEBE.BeBeCtrl.1", 0xe1b8d1ac, 0xcb00, 0x48df, 0x8c, 0xbf, 0xea, 0xab, 0x67, 0x61, 0x94, 0xf1) ///////////////////////////////////////////////////////////////////////////// // Type library ID and version IMPLEMENT_OLETYPELIB(CBeBeCtrl, _tlid, _wVerMajor, _wVerMinor) ///////////////////////////////////////////////////////////////////////////// // Interface IDs const IID BASED_CODE IID_DBeBe = { 0xde91cda3, 0x7eb0, 0x469b, { 0xac, 0xd8, 0x15, 0x5, 0x79, 0xd2, 0xd6, 0x68 } }; const IID BASED_CODE IID_DBeBeEvents = { 0x3501cacc, 0x2429, 0x455a, { 0xad, 0x11, 0x5d, 0xfa, 0x3a, 0xf8, 0xc, 0xae } }; ///////////////////////////////////////////////////////////////////////////// // Control type information static const DWORD BASED_CODE _dwBeBeOleMisc = OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT | OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE; IMPLEMENT_OLECTLTYPE(CBeBeCtrl, IDS_BEBE, _dwBeBeOleMisc) ///////////////////////////////////////////////////////////////////////////// // CBeBeCtrl::CBeBeCtrlFactory::UpdateRegistry - // Adds or removes system registry entries for CBeBeCtrl BOOL CBeBeCtrl::CBeBeCtrlFactory::UpdateRegistry(BOOL bRegister) { // TODO: Verify that your control follows apartment-model threading rules. // Refer to MFC TechNote 64 for more information. // If your control does not conform to the apartment-model rules, then // you must modify the code below, changing the 6th parameter from // afxRegApartmentThreading to 0. if (bRegister) return AfxOleRegisterControlClass( AfxGetInstanceHandle(), m_clsid, m_lpszProgID, IDS_BEBE, IDB_BEBE, afxRegApartmentThreading, _dwBeBeOleMisc, _tlid, _wVerMajor, _wVerMinor); else return AfxOleUnregisterClass(m_clsid, m_lpszProgID); } // Han ///////////////////////////////////////////////////////////// // Interface map for IObjectSafety BEGIN_INTERFACE_MAP( CBeBeCtrl, COleControl ) INTERFACE_PART(CBeBeCtrl, IID_IObjectSafety, ObjSafe) END_INTERFACE_MAP() ///////////////////////////////////////////////////////////// // IObjectSafety member functions ULONG FAR EXPORT CBeBeCtrl::XObjSafe::AddRef() { METHOD_PROLOGUE(CBeBeCtrl, ObjSafe) return pThis->ExternalAddRef(); } ULONG FAR EXPORT CBeBeCtrl::XObjSafe::Release() { METHOD_PROLOGUE(CBeBeCtrl, ObjSafe) return pThis->ExternalRelease(); } HRESULT FAR EXPORT CBeBeCtrl::XObjSafe::QueryInterface( REFIID iid, void FAR* FAR* ppvObj) { METHOD_PROLOGUE(CBeBeCtrl, ObjSafe) return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; const DWORD dwNotSupportedBits = ~ dwSupportedBits; HRESULT STDMETHODCALLTYPE CBeBeCtrl::XObjSafe::GetInterfaceSafetyOptions( /* [in] */ REFIID riid, /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions) { METHOD_PROLOGUE(CBeBeCtrl, ObjSafe) HRESULT retval = ResultFromScode(S_OK); // does interface exist? IUnknown FAR* punkInterface; retval = pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface); if (retval != E_NOINTERFACE) { // interface exists punkInterface->Release(); // release it--just checking! } // we support both kinds of safety and have always both set, // regardless of interface *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits; return retval; // E_NOINTERFACE if QI failed } HRESULT STDMETHODCALLTYPE CBeBeCtrl::XObjSafe::SetInterfaceSafetyOptions( /* [in] */ REFIID riid, /* [in] */ DWORD dwOptionSetMask, /* [in] */ DWORD dwEnabledOptions) { METHOD_PROLOGUE(CBeBeCtrl, ObjSafe) // does interface exist? IUnknown FAR* punkInterface; pThis->ExternalQueryInterface(&riid, (void**)&punkInterface); if (punkInterface) { // interface exists punkInterface->Release(); // release it--just checking! } else { // interface doesn't exist return ResultFromScode(E_NOINTERFACE); } // can't set bits we don't support if (dwOptionSetMask & dwNotSupportedBits) { return ResultFromScode(E_FAIL); } // can't set bits we do support to zero dwEnabledOptions &= dwSupportedBits; // (we already know there are no extra bits in mask ) if ((dwOptionSetMask & dwEnabledOptions) != dwOptionSetMask) { return ResultFromScode(E_FAIL); } // don't need to change anything since we're always safe return ResultFromScode(S_OK); } ///////////////////////////////////////////////////////////////////////////// // CBeBeCtrl::CBeBeCtrl - Constructor CBeBeCtrl::CBeBeCtrl() { InitializeIIDs(&IID_DBeBe, &IID_DBeBeEvents); // TODO: Initialize your control's instance data here. } ///////////////////////////////////////////////////////////////////////////// // CBeBeCtrl::~CBeBeCtrl - Destructor CBeBeCtrl::~CBeBeCtrl() { // TODO: Cleanup your control's instance data here. } ///////////////////////////////////////////////////////////////////////////// // CBeBeCtrl::OnDraw - Drawing function void CBeBeCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { // TODO: Replace the following code with your own drawing code. TRACE("CBeBeCtrl::OnDraw !!!\n"); m_rcDraw = rcBounds; // Draw Color-Board BITMAP bmInfo; m_bmColorBoard.GetBitmap(&bmInfo); CDC boardDC; boardDC.CreateCompatibleDC(pdc); CBitmap *pbmBoard = boardDC.SelectObject(&m_bmColorBoard); // Draw Image if (m_image.IsDataNull()) { // Draw Background CImage image = m_imageMask; image.Draw(boardDC.GetSafeHdc(), m_rcImage); boardDC.DrawText("No Image!!!", -1, m_rcImage, DT_CENTER | DT_VCENTER); } else { CImage image = m_image; m_imageHide.MaskCopy2(image); m_imageMask.MaskCopy(255, 255, 255, image); image.Draw(boardDC.GetSafeHdc(), m_rcImage); } if (m_imagePool.GetSize() > 0) { CImage image = m_imagePool[m_nImageIndex]; image.Zoom(m_rcPrev.Width(), m_rcPrev.Height()); m_prevMask.MaskCopy(255, 255, 255, image); image.Draw(boardDC.GetSafeHdc(), m_rcPrev); } boardDC.FillSolidRect(m_rcSelect, m_crSelect); pdc->BitBlt(0, 0, rcBounds.Width(), rcBounds.Height(), &boardDC, 0, 0, SRCCOPY); // ¸Þ¸ð¸® ºñÆ®¸ÊÀ» ½ÇÁ¦ CDC¿¡ Àü¼ÛÇÑ´Ù boardDC.SelectObject(pbmBoard); } ///////////////////////////////////////////////////////////////////////////// // CBeBeCtrl::DoPropExchange - Persistence support void CBeBeCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); // TODO: Call PX_ functions for each persistent custom property. } ///////////////////////////////////////////////////////////////////////////// // CBeBeCtrl::OnResetState - Reset control to default state void CBeBeCtrl::OnResetState() { COleControl::OnResetState(); // Resets defaults found in DoPropExchange // TODO: Reset any other control state here. } ///////////////////////////////////////////////////////////////////////////// // CBeBeCtrl::AboutBox - Display an "About" box to the user void CBeBeCtrl::AboutBox() { CDialog dlgAbout(IDD_ABOUTBOX_BEBE); dlgAbout.DoModal(); } ///////////////////////////////////////////////////////////////////////////// // CBeBeCtrl message handlers int CBeBeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here // µÇµ¹¸®±â, ´Ù½ÃÇϱâ, ÀμâÇϱâ, ³ª°¡±â ¹öÆ° CRect rcButton(45, 85, 45 + 124, 85 + 52); m_btnUndo.Create(NULL, WS_CHILD|WS_VISIBLE|WS_DISABLED|BS_OWNERDRAW, rcButton, this, IDC_BTN_UNDO); rcButton.left = 179; rcButton.top = 85; rcButton.right = 179 + 131; rcButton.bottom = 85 + 34; m_btnRedo.Create(NULL, WS_CHILD|WS_VISIBLE|WS_DISABLED|BS_OWNERDRAW, rcButton, this, IDC_BTN_REDO); rcButton.left = 318; rcButton.top = 84; rcButton.right = 318 + 133; rcButton.bottom = 84 + 49; m_btnPrint.Create(NULL, WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, rcButton, this, IDC_BTN_PRINT); rcButton.left = 461; rcButton.top = 85; rcButton.right = 461 + 103; rcButton.bottom = 85 + 34; m_btnExit.Create(NULL, WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, rcButton, this, IDC_BTN_EXIT); // ¹Ì¸®º¸±â ¹öÆ° rcButton.left = 673; rcButton.top = 370; rcButton.right = 673 + 33; rcButton.bottom = 370 + 33; m_btnPrev.Create(NULL, WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, rcButton, this, IDC_BTN_PREV); rcButton.left = 751; rcButton.top = 370; rcButton.right = 751 + 33; rcButton.bottom = 370 + 33; m_btnNext.Create(NULL, WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, rcButton, this, IDC_BTN_NEXT); m_btnUndo.LoadBitmaps(IDB_UNDO_UP, IDB_UNDO_DN, NULL, IDB_UNDO_DS); m_btnRedo.LoadBitmaps(IDB_REDO_UP, IDB_REDO_DN, NULL, IDB_REDO_DS); m_btnPrint.LoadBitmaps(IDB_PRINT_UP, IDB_PRINT_DN, NULL, NULL); m_btnExit.LoadBitmaps(IDB_EXIT_UP, IDB_EXIT_DN, NULL, NULL); m_btnPrev.LoadBitmaps(IDB_PREV_UP, IDB_PREV_DOWN, NULL, NULL); m_btnNext.LoadBitmaps(IDB_NEXT_UP, IDB_NEXT_DOWN, NULL, NULL); m_bmColorBoard.LoadBitmap(IDB_BOARD); CBitmap maskImage; maskImage.LoadBitmap(IDB_IMAGE_MASK); CImage temp(maskImage); m_imageMask = temp; CBitmap maskImage2; maskImage2.LoadBitmap(IDB_PREV_MASK); CImage temp2(maskImage2); m_prevMask = temp2; m_rcImage.left = 31; m_rcImage.top = 155; m_rcImage.right = 31 + 572; m_rcImage.bottom = 155 + 452; // Palette m_rcPalette.left = 651; m_rcPalette.top = 492; m_rcPalette.right = 651 + 145; m_rcPalette.bottom = 492 + 133; // Select m_rcSelect.left = 744; m_rcSelect.top = 445; m_rcSelect.right = 744 + 52; m_rcSelect.bottom = 445 + 37; m_crSelect = RGB(255, 0, 132); m_rcPrev.left = 641; m_rcPrev.top = 197; m_rcPrev.right = 641 + 174; m_rcPrev.bottom = 197 + 158; m_nImageIndex = 0; FireOnInitImage(); return 0; } void CBeBeCtrl::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (m_rcDraw.PtInRect(point)) { if (m_rcImage.PtInRect(point)) { if (m_imageHide.IsDataNull()) return ; // »ö»ó Ä¥Çϱâ long x = point.x; long y = point.y; x -= m_rcImage.left; y -= m_rcImage.top; unsigned char r = GetRValue(m_crSelect); unsigned char g = GetGValue(m_crSelect); unsigned char b = GetBValue(m_crSelect); if (m_imageHide.FillColor(x, y, r, g, b)) { HISTORY history; history.crNew = RGB(r, g, b); RGBT crTemp = m_imageHide.GetMaskColor(); history.crOld = RGB(crTemp.r, crTemp.g, crTemp.b); history.ptFill.x = x; history.ptFill.y = y; m_history.NewFill(history); if (m_history.UndoState() == FALSE) m_btnUndo.EnableWindow(FALSE); else m_btnUndo.EnableWindow(TRUE); if (m_history.RedoState() == FALSE) m_btnRedo.EnableWindow(FALSE); else m_btnRedo.EnableWindow(TRUE); } Invalidate(FALSE); } else if (m_rcPalette.PtInRect(point)) { // »ö»ó ¼±ÅÃÇϱâ CClientDC dc(this); COLORREF crColor = dc.GetPixel(point); if (crColor != 0) { m_crSelect = crColor; Invalidate(FALSE); } } else if (m_rcPrev.PtInRect(point)) { if (m_imagePool.GetSize() > 1) { m_image = m_imagePool[m_nImageIndex]; if (m_image.GetHandle()) { m_imageHide = m_image; m_imageHide.Treshold(168); } m_history.Clear(); m_btnUndo.EnableWindow(FALSE); m_btnRedo.EnableWindow(FALSE); Invalidate(FALSE); } } } COleControl::OnLButtonUp(nFlags, point); } void CBeBeCtrl::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default static long m_nPrevCursor = -1; if (m_rcImage.PtInRect(point)) m_nMouseCursor = MT_FILLCOLOR; else m_nMouseCursor = MT_NORMAL; if (m_nPrevCursor != m_nMouseCursor) { SetCursorType(); m_nPrevCursor = m_nMouseCursor; } COleControl::OnMouseMove(nFlags, point); } void CBeBeCtrl::SetImageURL(LPCTSTR szURL) { // TODO: Add your dispatch handler code here if (szURL == _T("")) return ; m_szImageURL = szURL; long nIndex = m_szImageURL.GetLength() -1; TCHAR ch = m_szImageURL.GetAt(nIndex); if (ch != '/') m_szImageURL += '/'; DoLoadImage(); } BOOL CBeBeCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default switch (m_nMouseCursor) { case MT_FILLCOLOR: if (m_image.IsDataNull() == FALSE) SetCursor(AfxGetApp()->LoadCursor(IDC_CUR_BRUSH)); break; default: SetCursor(::LoadCursor(NULL, IDC_ARROW)); break; } return TRUE; // return COleControl::OnSetCursor(pWnd, nHitTest, message); } // À̹ÌÁö¸¦ DIB À̹ÌÁö·Î ¸¸µç´Ù. void CBeBeCtrl::DoDraw(HDC hDC, CRect rcDraw) { // Draw Image if (m_image.IsDataNull()) { // Draw Background FillRect(hDC, rcDraw, (HBRUSH)GetStockObject(WHITE_BRUSH)); DrawText(hDC, "No Image!!!", -1, rcDraw, DT_CENTER | DT_VCENTER); } else { CRect rcImage; rcImage.top = 0; rcImage.bottom = m_image.GetHeight(); rcImage.left = 0; rcImage.right = m_image.GetWidth(); CImage image = m_image; m_imageHide.MaskCopy2(image); image.Draw(hDC, rcImage, rcDraw); } } void CBeBeCtrl::DoPrint() { DOCINFO doc; PRINTDLG pd; HDC hPrtDC; // ÇÁ¸°ÅÍ¿¡ °üÇÑ Á¤º¸¸¦ ±¸ÇÏ°í DC¸¦ ¸¸µç´Ù. memset(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.Flags = PD_RETURNDC; pd.hwndOwner = this->m_hWnd; pd.nFromPage = 1; pd.nToPage = 1; pd.nMinPage = 1; pd.nMaxPage = 1; pd.nCopies = 1; PrintDlg(&pd); hPrtDC = pd.hDC; if (hPrtDC == NULL) return; // Àμâ ÀÛ¾÷À» ½ÃÀÛÇÑ´Ù. doc.cbSize = sizeof(DOCINFO); doc.lpszDocName = "Test Document"; doc.lpszOutput = NULL; doc.lpszDatatype = NULL; doc.fwType = 0; long Result = StartDoc(hPrtDC, &doc); if (Result <= 0) { DeleteDC(hPrtDC); return ; } Result = StartPage(hPrtDC); if (Result <= 0) { DeleteDC(hPrtDC); return ; } // Ãâ·ÂÀ» º¸³½´Ù. long xpage = GetDeviceCaps(hPrtDC, HORZRES); long ypage = GetDeviceCaps(hPrtDC, VERTRES); // ÇÁ¸°ÅÍÀÇ Çػ󵵸¦ ±¸ÇÑ´Ù. long dpiX = GetDeviceCaps(hPrtDC, LOGPIXELSX); long dpiY = GetDeviceCaps(hPrtDC, LOGPIXELSY); // Rectangle(hPrtDC, 0, 0, xpage, ypage); Result = GetDeviceCaps(hPrtDC, RASTERCAPS) & RC_BITBLT; if (!Result) { DeleteDC(hPrtDC); return ; } // À̹ÌÁö¸¦ ±×¸°´Ù. CRect rcDraw(dpiX, dpiY, xpage-dpiX, ypage-dpiY); long nWidth = rcDraw.Width(); long nHeight = rcDraw.Height(); // À̹ÌÁö¸¦ ºñÀ²¿¡ ¸Â°Ô È®´ë/Ãà¼Ò ÇÏ°í ³ª¸ÓÁö´Â ¿©¹éó¸®ÇÑ´Ù. double fTemp = (double)m_image.GetWidth() / (double)m_image.GetHeight(); long nNewWidth = (long)((double)nHeight * fTemp + 0.5); if (nNewWidth > nWidth) { long nNewHeight = (long)((double)nWidth / fTemp + 0.5); long nMarginH = (nHeight - nNewHeight) >> 1; rcDraw.top += nMarginH; rcDraw.bottom = rcDraw.top + nNewHeight - 1; } else { long nMarginW = (nWidth - nNewWidth) >> 1; rcDraw.left += nMarginW; rcDraw.right = rcDraw.left + nNewWidth - 1; } DoDraw(hPrtDC, rcDraw); // Ãâ·ÂÀ» Á¾·áÇÑ´Ù. Result = EndPage(hPrtDC); if (Result <= 0) { DeleteDC(hPrtDC); return ; } // Àμâ ÀÛ¾÷À» ³¡³½´Ù. Result = EndDoc(hPrtDC); DeleteDC(hPrtDC); } void CBeBeCtrl::DoUndo() { HISTORY history = m_history.Undo(); if (history.ptFill.x < 0) return ; unsigned char r = GetRValue(history.crOld); unsigned char g = GetGValue(history.crOld); unsigned char b = GetBValue(history.crOld); if (m_imageHide.FillColor(history.ptFill.x, history.ptFill.y, r, g, b)) { if (m_history.UndoState() == FALSE) m_btnUndo.EnableWindow(FALSE); else m_btnUndo.EnableWindow(TRUE); if (m_history.RedoState() == FALSE) m_btnRedo.EnableWindow(FALSE); else m_btnRedo.EnableWindow(TRUE); Invalidate(FALSE); } } void CBeBeCtrl::DoRedo() { HISTORY history = m_history.Redo(); if (history.ptFill.x < 0) return ; unsigned char r = GetRValue(history.crNew); unsigned char g = GetGValue(history.crNew); unsigned char b = GetBValue(history.crNew); if (m_imageHide.FillColor(history.ptFill.x, history.ptFill.y, r, g, b)) { if (m_history.UndoState() == FALSE) m_btnUndo.EnableWindow(FALSE); else m_btnUndo.EnableWindow(TRUE); if (m_history.RedoState() == FALSE) m_btnRedo.EnableWindow(FALSE); else m_btnRedo.EnableWindow(TRUE); Invalidate(FALSE); } } BOOL FindImgSrc(LPSTR lpTag, CString *pSrc) { LPSTR lpSrc; // ¾ÕÀÇ whitespace¿Í '<' Á¦°Å while(*lpTag) { if (*lpTag == '<' || *lpTag == ' ' || *lpTag == '\t') lpTag++; else break; } // ù¹ø° ÅäÅ«À» ºÐ¸®Çس½´Ù. CString strTag; while(*lpTag) { if (*lpTag != '>' && *lpTag != ' ' && *lpTag != '\t' && *lpTag != '\n') strTag += *lpTag++; else break; } if (strTag.CompareNoCase("a") == 0) // a ű׸¦ ãÀº °æ¿ì { // lpTokenÀ» ¸ðµÎ ¼Ò¹®ÀÚ·Î º¯°æÇÑ´Ù. strlwr(lpTag); // ÀÌÁ¦ href¸¦ ã´Â´Ù. if (lpSrc = strstr(lpTag, "href=")) { lpSrc += 5; lpSrc = strtok(lpSrc, " >\t\n"); *pSrc = lpSrc; } else return FALSE; } else return FALSE; return TRUE; } BOOL GetImageTags(LPSTR szBuffer, CArray &aszImageList) { BOOL InTag=FALSE; CStringList RList; int i = 0,j=0; POSITION pos = NULL; int nLen = strlen(szBuffer); LPCTSTR lpsz = szBuffer; CString str,hString; if (nLen <= 0) return FALSE; str=""; while (nLen) { if( *lpsz == '<') InTag=TRUE; if(InTag==TRUE) str += szBuffer[j]; if( *lpsz == '>') { if (str.GetLength() > 5) { if (str.GetAt(1) != '/') RList.AddTail(str); } str =""; InTag=FALSE; } ++lpsz; j++; nLen--; } int count = RList.GetCount(); CString strSrc; for (i = 0; i < count; i++) { if ((pos = RList.FindIndex(i)) != NULL) { str = RList.GetAt(pos); if (FindImgSrc((LPSTR)(LPCSTR)str, &strSrc)) { str = strSrc; str.MakeLower(); // À̹ÌÁö ÆÄÀϸ¸À» Ãß°¡ÇÑ´Ù. if (str.Find(".bmp") > -1 || str.Find(".gif") > -1 || str.Find(".jpg") > -1) { // À̹ÌÁö ¸í¸¸ À߶󳽴Ù. long nIndex = strSrc.ReverseFind('/'); if (nIndex > 0) str = strSrc.Mid(nIndex+1); else str = strSrc; // Ãß°¡Çϱâ Àü¿¡ '¿Í "¸¦ Á¦°ÅÇÑ´Ù. str.Remove('\''); str.Remove('"'); aszImageList.Add(str); } } } } count = aszImageList.GetSize(); if (count > 0) return TRUE; return FALSE; } void CBeBeCtrl::DoLoadImage() { // À̹ÌÁö ¸®½ºÆ® °¡Á®¿À±â. CArray aszImageList; CInternetSession session; CInternetFile *iFile = NULL; try { iFile = (CInternetFile *)session.OpenURL(m_szImageURL); if (iFile) { long nFileSize = iFile->GetLength(); char * szBuff = new char[nFileSize + 1]; UINT nRead = iFile->Read(szBuff, nFileSize); szBuff[nFileSize] = '\0'; GetImageTags(szBuff, aszImageList); delete szBuff; iFile->Close(); delete iFile; } } catch(CInternetException * pEx) { TCHAR lpszError[256]; pEx->GetErrorMessage( lpszError, 256, NULL ); CString szContent = lpszError; AfxMessageBox(szContent + "\nPlease confirm your url."); return ; } session.Close(); // À̹ÌÁö °¡Á®¿À±â. m_imagePool.RemoveAll(); CString szLocalImage; CString szImageURL; int nSize = aszImageList.GetSize(); for (long i = 0; i < nSize; i++) { szImageURL = aszImageList.GetAt(i); szImageURL.MakeLower(); szLocalImage = "C:\\Image001"; if (szImageURL.Find(".bmp") > -1) szLocalImage += ".bmp"; else if(szImageURL.Find(".gif") > -1) szLocalImage += ".gif"; else if(szImageURL.Find(".jpg") > -1) szLocalImage += ".jpg"; else continue ; szImageURL = m_szImageURL + aszImageList.GetAt(i); URLDownloadToFile(NULL, szImageURL, szLocalImage, 0, NULL); m_image.Load(szLocalImage); m_image.Zoom(m_rcImage.Width(), m_rcImage.Height()); m_image.SetLineColor(0, 0, 0); if (m_image.GetHandle()) m_imagePool.Add(m_image); } if (m_image.GetHandle()) { m_imageHide = m_image; m_imageHide.Treshold(168); } m_history.Clear(); m_btnUndo.EnableWindow(FALSE); m_btnRedo.EnableWindow(FALSE); Invalidate(FALSE); } void CBeBeCtrl::SetCursorType() { switch (m_nMouseCursor) { case MT_FILLCOLOR: if (m_image.IsDataNull() == FALSE) SetCursor(AfxGetApp()->LoadCursor(IDC_CUR_BRUSH)); break; default: SetCursor(::LoadCursor(NULL, IDC_ARROW)); break; } } void CBeBeCtrl::DoExit() { // HWND hWnd = ::FindWindow(NULL, "BeBe - Microsoft Internet Explorer"); CComPtr pClientSite; CComPtr pContainer; CComPtr pServiceProvider; CComPtr pIWB2; pClientSite = GetClientSite(); pClientSite->GetContainer( &pContainer ); pContainer->QueryInterface( &pServiceProvider ); // Active X ControlÀº IE¿¡¸¸ ¿Ã·Á³õ´Â °ÍÀÌ ¾Æ´Ï´Ï ½ÇÆп¡ ÁÖÀÇ pServiceProvider->QueryService( SID_SWebBrowserApp, IID_IWebBrowser2, (void**) &pIWB2 ); if (pIWB2 != NULL) { HWND hWnd = NULL; pIWB2->get_HWND( (long *) &hWnd ); if (hWnd != NULL) { ::SendMessage(hWnd, WM_ACTIVATE, 0L, 0L); ::SendMessage(hWnd, WM_NCDESTROY, 0L, 0L); ::SendMessage(hWnd, WM_DESTROY, 0L, 0L); } else exit(0); } else exit(0); } BOOL CBeBeCtrl::OnCommand(WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class switch (LOWORD(wParam)) { case IDC_BTN_UNDO: DoUndo(); break; case IDC_BTN_REDO: DoRedo(); break; case IDC_BTN_PRINT: DoPrint(); break; case IDC_BTN_EXIT: DoExit(); break; case IDC_BTN_PREV: DoImagePrev(); break; case IDC_BTN_NEXT: DoImageNext(); break; } return COleControl::OnCommand(wParam, lParam); } void CBeBeCtrl::DoImagePrev() { m_nImageIndex--; if (m_nImageIndex < 0) m_nImageIndex = 0; Invalidate(FALSE); } void CBeBeCtrl::DoImageNext() { long nSize = m_imagePool.GetSize(); m_nImageIndex++; m_nImageIndex = m_nImageIndex % nSize; Invalidate(FALSE); }