CListCtrl에서 깜박임이 덜한 SetItemText

//--------------------------------------------------------------------------//
//Fuction        : UpdateListItem
//Parameter : CListCtrl* pList, int nIndex, int nSubitem, LPCTSTR lpszText
//Return        : BOOL
//Note                : pList의 nIndex, nSubitem의 텍스트를 lpszText로 바꾼다.
//            같은 값이 벌써 들어가 있으면 FALSE, 새로운 값으로 대체 하면 TRUE
//--------------------------------------------------------------------------//
BOOL UpdateListItem(CListCtrl* pList, int nIndex, int nSubitem, LPCTSTR lpszText)
{

   CString strText = pList->GetItemText( nIndex, nSubitem );
       if ( strText.CompareNoCase( lpszText ) )
       {
       pList->SetItemText( nIndex, nSubitem, lpszText );
               return TRUE;
       }

       return FALSE;
}

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

원리는 간단합니다.
쓰려는 Text와 쓰여져있는 Text를 비교해 틀릴때만 써주는거죠.
각 Item별로 해줘도 되지만..
함수하나로 만들어 봤습니다.

좋은 시간 되세요.

CComboBox에서 ItemData와 ItemText찾기

//--------------------------------------------------------------------------//
//Fuction        : FindComboString
//Parameter : CComboBox* pCombo, DWORD dwSearch, CString *pstrDest
//Return        : int
//Note                : pCombo에서 Callback Item중 dwSearch를 찾아
//            Index를 리턴하고, 해당 Index의 List Text를 pstrDest로 넘긴다.
//--------------------------------------------------------------------------//
int FindComboString(CComboBox* pCombo, DWORD dwSearch, CString *pstrDest)
{
       for(int i=pCombo->GetCount()-1; i>=0; i--)
       {
               if ( pCombo->GetItemData( i ) == dwSearch )
               {
                       pCombo->GetLBText( i, *pstrDest );
           return i;
               }
       }

       return -1;
}



//--------------------------------------------------------------------------//
//Fuction        : FindComboString
//Parameter : CComboBox* pCombo, CString strSearch, DWORD* pdwDest
//Return        : int
//Note                : pCombo에서 List Text중 strSearch를 찾아
//            Index를 리턴하고, 해당 Index의 Callback Item을 pdwDest로 넘긴다
//--------------------------------------------------------------------------//
int FindComboDword(CComboBox* pCombo, CString strSearch, DWORD* pdwDest)
{
       CString str="";
       for(int i=pCombo->GetCount()-1; i>=0; i--)
       {
               pCombo->GetLBText( i, str );
               if ( !str.Compare( strSearch ) )
               {
           *pdwDest = (DWORD)pCombo->GetItemData( i );
                       return i;
               }
       }
       return -1;
}

전체경로를 받아 파일이름을 제외한 경로만 구하기

//-------------------------------------------------------------------------------------//
// Function                        : OnlyDirecory
// Parameter                : CString strMoney
// Return                        : LPTSTR strFull                        
// Note                                : 인자로 받은 전체파일이름의 파일이 있는 경로를 리턴한다.
//-------------------------------------------------------------------------------------//
LPTSTR OnlyDirecory(LPTSTR strFull)
{
       TCHAR* pPos = strFull + strlen( strFull );

       while ( strncmp( pPos, "\\", 1 ) && pPos != strFull )
               pPos--;
       *pPos = '\0';

       return strFull;
}

CTreeCtrl에서 ItemData 찾기 (자식노드 포함)

//-------------------------------------------------------------------------------------//
// Function         : FindTreeData
// Parameter        : HTREEITEM hItem, DWORD dwData
// Return           : HTREEITEM
// Note             : hItem이하 모든 모든 노드에서 dwData를 찾는다.
//-------------------------------------------------------------------------------------//
HTREEITEM FindTreeData(CTreeCtrl* pTree, HTREEITEM hItem, DWORD dwData)
{
       HTREEITEM hitemFind, hItemChile, hItemSibling;
       hitemFind = hItemChile = hItemSibling = NULL;


       if ( pTree->GetItemData( hItem ) == dwData )
       {
               hitemFind = hItem;
       }
       else
       {
               // 자식 노드를 찾는다.
               hItemChile = pTree->GetChildItem( hItem );
               if ( hItemChile )
               {
                       hitemFind = FindTreeData( pTree, hItemChile, dwData );

               }

               // 형제노드를 찾는다.
               hItemSibling = pTree->GetNextSiblingItem( hItem );
               if ( hitemFind==NULL && hItemSibling )
               {
                       hitemFind = FindTreeData( pTree, hItemSibling, dwData );
               }
       }
   
       return hitemFind;
}

MFC에서 .NET스타일의 메뉴를 사용해 보자


NewMenu


The NewMenu is published on
CodeProject
. There you will find the discussion board.






This is a prerelease of NewMenu 1.13 (will be published shortly)





Released NewMenu 1.11 (Published on codeproject)
















STYLE_XPSTYLE_ICYSTYLE_ORIGINAL


Introduction


This class, CNewMenu, implements owner drawn menus derived
from the CMenu class. The coal of this class is to have menus with
the same look as the new menu from the Microsoft products. In the other hand an
easy use of a new menu class with Icons and Title support.
I was inspired from the great class BCMenu from Brent Corkum. I took some ideas
and almost every function, but reimplemented almost the whole code and expanded
it with some other nice functions. It was a hard work to change the look of the
whole menu that belongs to an application, changing border and adding shading.
Furthermore, it was tricky changing all menus under windows 2000 or system menu
under Windows XP when you are using themes. Over all, I hope it's now easy
enough for you to use this class in new applications.


This new menu works under Windows 95/98/Me and Windows NT4.0/2000/XP. When you
like to use Chinese or some other special characters, you have to compile your
project with Unicode. But keep in mind you must have installed the Unicode
libraries with the Visual studio otherwise you get a linking error.


Additional when you want that your program works on all platforms, you have to
compile it with the Visual Studio 6.0. I did not find out why the drawing don't
work fine when it is compiled with the Visual Studio 7.0 under Windows NT 4.0.
Furthermore when you do not like the flat border you can use the
STYLE_XXX_NOBORDER and then menus will have the standard menu border from the
system.


Nice Title in Menus











Oh yes, its also possible to add a title to menu. You can add a title on the
top or on the left side of a menu. You can have a gradient or a solid color as
background. With the function SetMenuTitle you can add or remove a
title from a menu. The gradient drawing works also on Windows 95.
// Set a title to the system menu 
m_SystemNewMenu.SetMenuTitle(_T("New Menu Sample"),
MFT_GRADIENT|MFT_LINE|MFT_CENTER);

New icons effects brightening, glooming and graying








Under menu style XP you have the possibility to enable or
disable the additional drawing style to icons. Disabled icons become a grayed
look and non selected icons become a gloom look. You can see the
different between those drawing styles in the sample.

How to use the CNewMenu in a project




  1. The easiest way is to replace all CDialog, CFrameWnd, CMDIFrameWnd,
    CMDIChildWnd, CMiniFrameWnd
    and CMultiDocTemplate through
    the new classes CNewDialog, CNewFrameWnd,
    CNewMDIFrameWnd, CNewMDIChildWnd, CNewMiniFrameWnd

    and CNewMultiDocTemplate
    in your project.

  2. Set in the application, derived from CWinApp, the menustyle just
    before you create the frame or a dialog window in the function InitInstance.
    // Set drawing style of all menus to XP-Mode or STYLE_ORIGINAL
    CNewMenu::SetMenuDrawMode(CNewMenu::STYLE_XP);


  3. When you have a multi document template, add the loading code for menu icons
    just after creating the template.
    CNewMultiDocTemplate* pDocTemplate; 
    pDocTemplate = new CNewMultiDocTemplate(IDR_MDINEWTYPE,
    RUNTIME_CLASS(CMDINewMenuDoc),
    // custom MDI child frame
    RUNTIME_CLASS(CChildFrame),
    RUNTIME_CLASS(CMDINewMenuView));

    AddDocTemplate(pDocTemplate);


    // Loading toolbar icons into the menu
    pDocTemplate->m_NewMenuShared.LoadToolBar(IDR_DRAWBAR);



  4. Insert at the end of OnCreate function of the MainFrame the loading code for
    the icons. For example:
    m_DefaultNewMenu.LoadToolBar(IDR_MAINFRAME);


  5. Finally don't forget to include the definition from the "NewMenu.h" in stdafx.h
    and add NewMenu.cpp to the project.


  6. Now you are ready to use the class.

How to use the CNewMenu in a dialog-Application




  1. Set in the application the menustyle before you create the dialog in the
    function InitInstance.
    // Set drawing style of all menus to XP-Mode
    CNewMenu::SetMenuDrawMode(CNewMenu::STYLE_XP);


  2. Replace all CDialog to CNewDialog in your Project.
    For example base class from CAboutDlg.


  3. For loading bitmaps in to the menu the best place is in OnInitDialog
    function after calling the base class function.
    // CDialogDlg could be your Dialog.
    BOOL CDialogDlg::OnInitDialog()
    {
    // Call the baseclass
    CNewDialog::OnInitDialog();


    // Load icons to the menu


    m_DefaultNewMenu.LoadToolBar(IDR_MAINFRAME);
    }


  4. Don't forget to include the the definition from the "NewMenu.h" in stdafx.h and
    add NewMenu.cpp to the project.



How to use the CNewMenu in a special frame window




  1. Normally you should overwrite measureitem, menuchar and
    initmenupopup. For this purpose I use the CNewFrame template
    class. So you can replace 'CYourSpecialBase' with 'CNewFrame'
    in your project.


  2. But don't change it in IMPLEMENT_DYNAMIC, IMPLEMENT_SERIAL
    or IMPLEMENT_DYNACREATE the base class to the new one.
    IMPLEMENT_DYNAMIC(CYourNewSpecialFrame, CYourSpecialBase)


  3. Don't forget to change the baseclass in BEGIN_MESSAGE_MAP.
    BEGIN_MESSAGE_MAP(CYourNewSpecialFrame, CNewFrame) 
    //{{AFX_MSG_MAP(CYourNewSpecialFrame)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()


  4. For loading bitmaps in to the menu, you can add the code in OnCreate
    function.


  5. Finally don't forget to include the the definition from the "NewMenu.h" in
    stdafx.h and add NewMenu.cpp to the project.



How to use the CNewMenu in a MDI-Application




  1. Change in the the application class in the BOOL InitInstance() function
    the CMultiDocTemplate to CNewMultiDocTemplate
    CNewMultiDocTemplate* pDocTemplate; 
    pDocTemplate = new CNewMultiDocTemplate(IDR_MDINEWTYPE,
    RUNTIME_CLASS(CMDINewMenuDoc),
    // custom MDI child frame
    RUNTIME_CLASS(CChildFrame),
    RUNTIME_CLASS(CMDINewMenuView));
    AddDocTemplate(pDocTemplate);


  2. Now insert the following code for loading additional bitmaps from a toolbar
    into the menus.
    // Loading toolbar icons into the menu 
    pDocTemplate->m_NewMenuShared.LoadToolBar(IDR_DRAWBAR);


    // Set drawing style of all menus to XP-Mode
    CNewMenu::SetMenuDrawMode(CNewMenu::STYLE_XP);


  3. Change the base class from the main frame class (CMainFrame) from
    CMDIFrameWnd
    to CNewMDIFrame in definition and
    implementation file.
      // Change the base class in the following makro
    IMPLEMENT_DYNAMIC(CMainFrame, CNewMDIFrameWnd)

    // don't forget to change here the baseclass
    BEGIN_MESSAGE_MAP(CMainFrame, CNewMDIFrameWnd)
    //{{AFX_MSG_MAP(CMainFrame)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    // DO NOT EDIT what you see in these blocks of generated code !
    ON_WM_CREATE()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()


  4. Add at the end of int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    for loading bitmap in the default menu.
    m_DefaultNewMenu.LoadToolBar(IDR_MAINFRAME);


  5. Finally change the baseclass of the child frame from CMDIChildWnd to
    CNewMDIChildWnd. Do the same for all derived class CDialog
    to the base class of CNewDialog.


  6. Don't forget to include the the definition from the "NewMenu.h" in stdafx.h and
    add NewMenu.cpp to the project.



How to use the CNewMenu in a SDI-Application




  1. Set in the application the menustyle before you create the dialog in the
    function InitInstance.
    // Set drawing style of all menus to XP-Mode
    CNewMenu::SetMenuDrawMode(CNewMenu::STYLE_XP);


  2. Replace all CDialog to CNewDialog in your Project.


  3. Change the base class from the main frame class (CMainFrame) from
    CFrameWnd
    to CNewFrameWnd
    in definition and implementation file.

  4. Add at the end of int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    for loading bitmap in the default menu.
    m_DefaultNewMenu.LoadToolBar(IDR_MAINFRAME);


  5. Don't forget to include the the definition from the "NewMenu.h" in stdafx.h and
    add NewMenu.cpp to the project.



How to replace system menu in system dialogs


Sometimes it would be pretty to change the menu in MessageBox or in
CFileDialog too. But unfortunately a MessageBox has no base class for
owerwriting. An other problem has the file dialog, there are at least two
dialog and the CFileDialog does only subclass the child dialog of the shown
FileDialog. For those dialog, and some more, I added a special subclassing
mechanism for our work.


// Subclass dialog with system menu 
CNewMenuHelper myHelper(NEW_MENU_DIALOG_SUBCLASS|NEW_MENU_DIALOG_SYSTEM_MENU);
AfxMessageBox(_T("You must restart the application"),MB_OK);

Even thought what can I do when I do not want to have a menu border
replacing in the next shown dialog? It is very simple! Just place the
CNewMenuHelper before your call like in the following sample.


// Subclass dialog with normal border painting 
CNewMenuHelper myHelper(NEW_MENU_DEFAULT_BORDER);
AfxMessageBox(_T("You must restart the application"),MB_OK);

Color replacing of bitmaps with 16 colors


The MFC replace some colors depended of the chosen system colors. So when you
use a black line in the bitmap, the color black will be replaced with the
system color of COLOR_BTNTEXT. Following the color mapping map. By
the way, it is the same color mapping of the toolbars.


The color RGB(0x00,0x00,0x00) will be changed to COLOR_BTNTEXT       // black
The color RGB(0x80,0x80,0x80) will be changed to COLOR_BTNSHADOW // dark gray
The color RGB(0xC0,0xC0,0xC0) will be changed to COLOR_BTNFACE // bright gray
The color RGB(0xFF,0xFF,0xFF) will be changed to COLOR_BTNHIGHLIGHT // white

Adding Icons to Menus


There are several possibilities adding icons to menu. An easy way is with a
toolbar resource. But the developer studio support only 16 color for
toolbar-bitmaps. What you can do is: first define your toolbar; then replace
the saved toolbar-bitmap with a hicolor bitmap by hand. Additional you can
define every icon in a different bitmap and assign it to a menuitem. My way was
define a bitmap like in an image list, make a helper table with the resource id
of the bitmap, size of an icon and followed by the ids of the icons. The end of
the table must be marked with an id number NULL.


// Define the table
static WORD ToolId[] =
{ IDR_NEWMENU256, // Resource id of the bitmap-icons
16, 15, // Dimension of each icon


ID_FILE_NEW, // First icon's ID
ID_FILE_OPEN, // Second icon's ID
ID_FILE_SAVE, // and so on...

NULL}; // Marker for end of table

//Load the definition into menu with transparent color
m_DefaultNewMenu.LoadToolBar(ToolId,RGB(192,192,192));

How to add an icon to a submenu


It is very simple to add or change the title of a submenu entry when you know
the menu text. The helper function ModifyODMenu can be used.


// set the icon IDB_MORE_C to the submenu "More A"
m_NewMenuShared.ModifyODMenu(0,_T("More A"),IDB_MORE_C);

Menu under Windows 2000


It was a strange thing to detect, that under Windows 2000, you have a window
menu with handle 0x10012, which is shared to all application. (I think under
Windows 98 is the menu 0x0090). I don't know why, but this is also a reason of
the specialty for some effects belonging to subclassing menu. First when you
have disabled menu effects, the menu windows are alternating created or showed.
That means, first showed menu is mostly the special menu, never created nor
destroyed only showed and disabled, and the second is normal created and
destroyed after closing. The third time, sometime, the special window is showed
again and then the next menu is created normal. For this reason, when you
subclass the special menu, you are responsible to restore all values before
unsubclassing it. Be careful when you changing some flags or styles, because
the other applications like having the standard menu. You can also receive
bluescreen when you forget to unsubclass or when changing painting areas
belongs to that menu. Really ugly!!! Second, when you enabled menu effects
every shown menu is created new from scratch. For this reason it doesn't matter
when you don't restore all flags or styles!


But almost I forgot to explain how I got the goal to subclass all menus. Well,
for first, you can't subclass the system menu class #32768 from an application;
also I was looking for other possibility. I decide to create a windows hook for
all windows messages and catching all messages for creating a window. After
checking for the window class, when I found the menu class, I subclassed it.
But, how I can subclass the special menu, which is never created? I found, that
one of the first messages, which were sending to that menu, was 0x01E2 and one
of the latest WM_SHOWWINDOW. So I caught these messages for sub-
and unsubclassing the special menu. Only between those two messages you have
access to the special window!! Why? I don't know, but be careful.


How to paint the border


Well after I got it to subclass the menu window I can draw the border by
myself by processing WM_NCPAINT message. But how is the shade
made? Just before the menu is showed on the screen I save the menu region in a
bitmap, this is a reason why it does not work when the underground has been
changed, and combine it with a shade drawing. An other way would be using
layered windows, but this will not work on all systems like windows 95/98.


System menu under Windows XP


I thought owner drawing a menu is all time easy. But on Windows XP, with
themes enabled, it is a curious thing. Especially the main frame when the
system menu were displayed. Instead of owner drawing, the menu items were drawn
by the frame. The frame had painted the windows button of the width of the menu
at the place of the menu item :-) instead of drawing it. Strange! So I found a
workaround. I increased the menu items identifier before showing the menu and
restored after closing it. So, it works under Windows 2000 and XP.


Important info for debugging the new menu under Windows 2000


You should never stop debugging when you are in middle painting of the menus,
because the special menu wouldn't be restored nor unsubclassed. Furthermore
there were a lot of strange effects. It is not forbidden, but be careful and
have a lot time for rebooting the system when it doesn't work correctly after
stopping the debugger.


History


23 January 2003 - Version 1.13




  • SetMenuText fixed.

  • Menubar color with theme fixed.

  • Added some helper for borderhandling of non CNewMenu

10 November 2002 - Version 1.11




  • Border drawing with menu animation under Win 98 corrected.

  • Border drawing / repainting when submenu closed fixed.

  • New menu style ICY.

  • Helperclasses for changing system menu for CommonDialog.

30 July 2002 - Version 1.10




  • Sharing Icons between menu for saving GDI-Resources.

  • New effects for drawing icons under STYLE_XPxx.

  • Recoloring of menu icons by changing system colors.

  • Drawing of the scroll button by extreme big menus a little bit better.

  • Mixing different icon sizes in a menu is now supported but they are not zoomed
    to the same size.

Known bugs




  • Menu border with shade is not updated when underground has been changed.

  • Menu border is drawn in a wrong size after changing the menu border style under
    windows settings. But restart the application and then it will work again fine.

  • The High Contrast Mode is not supported with all right colors.






<출처>
http://www.podetti.com/NewMenu/

MFC에서 타이틀 변경은 어떻게 하나요?

메인 프레임의 타이틀은 변경을 해도
다른 작업을 하면 다시 원래대로 돌아갑니다.

"프로젝트이름 - 문서이름"

이렇게 되는데
바꾸려면 어떻게 하나요?

MFC용 ADO클래스

최신 포스트가 있습니다.
보시려면 여기를 클릭하세요.

-----------------------------------------------------------------------

MFC에서 DB를 연동하는 경우는 드문경우 입니다만,
공부를 목적으로 허접한 클래스 하나 만들어 봤습니다.

ADO가 성능면에서 떨어진다고는 하지만
ODBC셋팅이 별도 필요 없고, 소규모의 간단한 DB작업엔
괜찮을것 같아서 작업했습니다.

보시면 아시겠지만 가장 기초적인 작업만 할 수 있는 클래스 이구요
생성하면 커넥션을 엑티비티하는것이 아니고, Open으로 쿼리를 날리고,
그때마다 커넥션을 하므로 성능을 저하시키는 단점이 있습니다.
(차후 보완해야할 점입니다)


[CAdoDB.h] =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#pragma once

#import "C:program filescommon filessystemadomsado15.dll"
               no_namespace
               rename("EOF", "adoEOF")

class CAdoDB
{
public:
       CAdoDB(void);
       ~CAdoDB(void);
       BOOL Init(CString Filename);
       BOOL Open(CString sql, CString Filename = _T(""));
       BOOL IsEOF();
       CString GetValueString(CString Field);
       BOOL MoveNext();
       BOOL Close();

private:
       _RecordsetPtr m_pRs;
       CString m_strConnection;
       BOOL m_IsOpen;
};



[CAdoDB.cpp] =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#include "StdAfx.h"
#include "adodb.h"

CAdoDB::CAdoDB(void)
{
       if ( FAILED(m_pRs.CreateInstance(__uuidof(Recordset))) )
               AfxMessageBox(_T("com 객체 생성에 실패 하였습니다."), MB_OK, NULL);

       m_strConnection = _T("");
       m_IsOpen = FALSE;
}

CAdoDB::~CAdoDB(void)
{
}

BOOL CAdoDB::Init(CString Filename)
{
       if ( m_pRs==NULL )
               return FALSE;

       m_strConnection = _T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=") + Filename;

       return FALSE;
}


BOOL CAdoDB::Open(CString sql, CString Filename)
{
       HRESULT hr;

       if ( m_pRs==NULL )
               return FALSE;

       Close();

       if ( Filename.IsEmpty() && m_strConnection.IsEmpty() )
               return FALSE;

       m_strConnection = (Filename.IsEmpty())?(m_strConnection):(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=")+Filename);

       try
       {

               hr = m_pRs->Open( (LPTSTR)(LPCTSTR)sql, (LPTSTR)(LPCTSTR)m_strConnection,
                                                 adOpenForwardOnly, adLockOptimistic, adCmdUnknown);
       }
       catch(_com_error &e)
       {
               TRACE(" Description: %s
", (LPCTSTR) e.Description());
       }
       catch(...)
       {
               TRACE("*** Unhandled Exception ***");
       }

       if ( SUCCEEDED( hr ) )
               m_IsOpen = TRUE;

       if ( sql.TrimLeft().Left(7).CollateNoCase( "SELECT " ) )
       {
               m_IsOpen = FALSE;
       }

       return SUCCEEDED( hr );
}

BOOL CAdoDB::IsEOF()
{
       if ( !m_IsOpen )
               return TRUE;

       return (BOOL)m_pRs->GetadoEOF();
}

CString CAdoDB::GetValueString(CString Field)
{
       if ( !m_IsOpen || IsEOF() )
               return "";

       _variant_t vt = m_pRs->GetCollect( (LPTSTR)(LPCTSTR)Field );

       return ( (vt.vt == VT_NULL)? ("") : vt );
}

BOOL CAdoDB::MoveNext()
{
       if ( !m_IsOpen )
               return FALSE;

       HRESULT hr = m_pRs->MoveNext();

       return SUCCEEDED( hr );
}

BOOL CAdoDB::Close()
{
       if ( !m_IsOpen )
               return TRUE;

       m_IsOpen = FALSE;

       return SUCCEEDED( m_pRs->Close() );
}

Http프로토콜을 이용한 파일 다운로드

[CODE type=c++]
//-------------------------------------------------------------------------------------//
// Function    : GetFile
// Parameter: LPCTSTR url, LPCTSTR filename
// Return    : CString            
//            - 성공하면 "YES" 실패하면 에러메시지를 반환
// Note        : url의 파일을 받아서 filename에 저장한다.
//            LPCTSTR url      - http프로토콜을 이용해 받아올 파일의 전체경로
//            LPCTSTR filename - 파일을 저장할 local경로
//-------------------------------------------------------------------------------------//
CString CInternetImageCtrl::GetFile(LPCTSTR url, LPCTSTR filename)
{
  HINTERNET hInternet, hURL;

  // 연결
  hInternet = InternetOpen( L"HTTPFILE", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

  if ( hInternet == NULL )
     return L"인터넷이 연결되어 있지 않습니다.";

// url
  hURL = InternetOpenUrl( hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
  if ( hURL==NULL )
  {
     InternetCloseHandle( hInternet );
     return L"서버오류로 연결할 수 없습니다.";
  }

  // 연결정보 확인
  TCHAR szStatusCode[10000];
  DWORD dwInfoSize = 10000;
  HttpQueryInfo(hURL, HTTP_QUERY_STATUS_CODE, szStatusCode, &dwInfoSize, NULL);


  long nStatusCode = _ttol(szStatusCode);
  if (nStatusCode == HTTP_STATUS_OK)
  { // 정상

     //  local file 생성
     HANDLE hFile;
     hFile = CreateFile( filename, GENERIC_WRITE, 0, NULL,
                         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );

     DWORD size;
     DWORD dwRead, dwWritten; //, Recv=0;
     char* buf = NULL;

     do
     {
        InternetQueryDataAvailable( hURL, &size, 0, 0 );
        buf = new char[size];
        InternetReadFile( hURL, buf, size, &dwRead );

        WriteFile( hFile, buf, dwRead, &dwWritten, NULL );
        delete buf;

     } while ( dwRead != 0 );

     CloseHandle( hFile );

  }
  else if (nStatusCode == HTTP_STATUS_NOT_FOUND)
  { // 404에러
     InternetCloseHandle( hInternet );
     InternetCloseHandle( hURL );
     return L"그림이 준비되지 않았습니다";
  } else
  { // 그외의 에러..
     InternetCloseHandle( hInternet );
     InternetCloseHandle( hURL );
     CString str;
     str.Format( L"Unknown Error
Err code : %d", nStatusCode);
     return str;
  }

  InternetCloseHandle( hInternet );
  InternetCloseHandle( hURL );

  return L"YES";
}


[/HTML][/CODE]

Http프로토콜을 이용한 파일 업로드

http서버에 올리는 소스이기 때문에
당연히 서버에 업로드 권한이 있어야 합니다.

[CODE type=c++]



void HttpPutFile(LPCTSTR wszServerURL, LPCTSTR wszRemoteFilePath,
                      LPCTSTR wszLocalFilePath, TCHAR nPort,
                      LPCTSTR wszLoginUserID, LPCTSTR wszLoginPassword )
{
/*
       TCHAR wszServerURL[100]         = L"solergy.com";
       TCHAR wszLocalFilePath[100]     = L"\Program Files\hanaro\Sign_AS\7250.bmp";
       TCHAR wszRemoteFilePath[100]  = L"/hanaro/sign/as/7250.bmp";
       TCHAR wszLoginUserID[100]       = L"";
       TCHAR wszLoginPassword[100]  = L"";
       TCHAR nPort                              = 80;
*/
       HINTERNET hInternet, hURL, hRequest;

       // 연결
       hInternet = InternetOpen( L"HTTPFILE", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
       if ( hInternet == NULL )
       {
               MessageBox( NULL, L"인터넷이 연결되어 있지 않습니다.", L"Warning", MB_OK);
               return;
       }

       // url
       hURL = InternetConnect( hInternet, wszServerURL, nPort,
                                                       wszLoginUserID, wszLoginPassword,
                                                       INTERNET_SERVICE_HTTP, 0, 0);
       if ( hURL==NULL )
       {
               InternetCloseHandle( hInternet );
               MessageBox( NULL, L"서버오류로 연결할 수 없습니다.", L"Warning", MB_OK);
               return;
       }

       INTERNET_BUFFERS        iBuf = {0};
       iBuf.dwStructSize = sizeof( INTERNET_BUFFERS );

       hRequest = HttpOpenRequest( hURL, L"PUT", wszRemoteFilePath, NULL, NULL, NULL, 0, 0 );
       if ( !hRequest )
       {
               InternetCloseHandle( hURL );
               InternetCloseHandle( hInternet );
               MessageBox( NULL, L"Request open Failed", L"Warning", MB_OK);
               return;
       }

       //  local file 오픈
       HANDLE hFile;
       hFile = CreateFile( wszLocalFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
                                               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
       if ( hFile == INVALID_HANDLE_VALUE )
       {
               MessageBox( NULL, L"Invalid read File", L"warning", MB_OK);
               InternetCloseHandle( hRequest );
               InternetCloseHandle( hInternet );
               InternetCloseHandle( hURL );
               return;
       }


       DWORD dwWritten;
       DWORD dwFileSize, dwFilePos=0, dwRead;

       dwFileSize = GetFileSize( hFile, NULL );
       iBuf.dwBufferTotal = dwFileSize;

       if( !HttpSendRequestEx( hRequest, &iBuf, NULL, HSR_INITIATE, 0 ) )
       {
               MessageBox( NULL, L"SendRequest Failed", L"warning", MB_OK);
               CloseHandle( hFile );
               InternetCloseHandle( hRequest );
               InternetCloseHandle( hInternet );
               InternetCloseHandle( hURL );
               return;
       }

       char buf[512];
       DWORD cnt=0;
       dwFilePos = 0;
       do
       {
               SetFilePointer( hFile, dwFilePos, NULL, FILE_BEGIN );
               if( !ReadFile( hFile, buf, sizeof(buf), &dwRead, NULL) )
               {
                       MessageBox( NULL, L"Local File read error", L"Warning", MB_OK);
                       break;
               };

               InternetSetFilePointer( hRequest, dwFilePos, NULL, FILE_BEGIN, 0 );
               if( !InternetWriteFile( hRequest, buf, dwRead, &dwWritten ) )
               {
                       MessageBox( NULL, L"Remote File write error", L"Warning", MB_OK);
                       break;
               };
               dwFilePos += dwWritten;

       } while ( dwRead == sizeof(buf) );


       CloseHandle( hFile );

       if( !HttpEndRequest( hRequest, NULL, 0, 0 ) )
       {
               MessageBox( NULL, L"EndRequest Failed", L"warning", MB_OK);
       }

       InternetCloseHandle( hRequest );
       InternetCloseHandle( hInternet );
       InternetCloseHandle( hURL );

}

[/HTML][/CODE]



EVC에서 다이얼로그에서 메인프레임의 타이틀 바꾸기..

여러 다이알로그를 띄우는 프로그램의 경우
그때그때마다 타이틀의 내용을 바꾸고 싶을때가 있습니다.
그런데 제가 아직 허접해서.. 쉽질 않더군여.. ㅡ.ㅡ
타이틀을 바꾸어도 포커스가 뷰로 옮겨가버리구여..

그래서 쉽게 바꿀 수 있는 방법을 생각해 봤습니다.

먼저. 메인프래임의 해더파일에 다음을 추가합니다.

public:
inline void SetFrameTitle(CString str) { SetWindowText( str ); };


그리고, 어디서든 참조하기 쉬운 해더파일에..
stdafx.h같은 곳에..

다음 코드를 추가합니다.
#define _SetTitle(str) { ((CMainFrame*)AfxGetMainWnd())->SetFrameTitle( (str) ); ::SetActiveWindow ( AfxGetMainWnd()->m_hWnd ); SetActiveWindow(); }

이렇게 하구나서.
무슨 다이알로그던 타이틀을 바꾸고 싶으면.
_SetTitle( _T("바꾸고 싶은 타이틀") );
이렇게만 코딩해 주면 됩니다.

일단 전 이렇게 구현했는데...
더 좋은 방법 있으시면 알려주세요.

좋은 시간 되세요. ^^