2009년 8월 21일 금요일

SO_REUSEADDR에 대하여

Server Program시 말그대로 이미 사용중인 Address에 대한 Bind 를 가능하게 하는 Option이다.
간혹 Server Program의 Terminate 를 통해 비정상적인 Socket의 Close가 발생하면,

해당 Address/port의 상태가 TIME_WAIT의 상태로 전이가 되어있다. 이때 이 Option을 사용하지 않으면, Bind가 불가능 하게 된다.

*주의할점 : 비정상적인 Packet이 유입될 가능성이 있다.

*예제코드 :

server_sockfd = socket( AF_INET, SOCK_STREAM, 0 );
if(server_sockfd == -1)
{
printf("Create socket Error\n");
exit(0);
}

int option = 1;
setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
// fcntl( server_sockfd, F_SETFL, O_NONBLOCK );// FASYNC );
if(bind( server_sockfd, (struct sockaddr*)&server_address, server_len ) != 0)
{
printf("Bind Error\n");
exit(0);
}


2009년 8월 18일 화요일

CSocket의 Connect시의 타임아웃 설정


CAsyncSocket m_Socket;
int port = _ttoi(g_UserInfo.ServerPort);
m_Socket.Create(0,SOCK_STREAM,0);

fd_set fdset;
FD_ZERO( &fdset );
FD_SET( m_Socket.m_hSocket, &fdset );
timeval timeOut;
timeOut.tv_sec = 3;
timeOut.tv_usec = 0;


// connect를 호출하긴 하지만 CAsync인 관계로 블럭되지 않고 통과

int ret = m_Socket.Connect(g_UserInfo.ServerIP,port);


if(ret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)

return FALSE;

// 여기서 3초간 블럭

if(select(0, NULL, &fdset, NULL, &timeOut) == SOCKET_ERROR)

return FALSE;

// 3초 후에 블럭이 플렸다면 현재 소켓이 열려 있는지 확인

if ( !FD_ISSET( m_Socket.m_hSocket, &fdset ) )

{

/// 3초만에 안열린 것이고
closesocket(m_Socket.m_hSocket);
m_Socket.m_hSocket = INVALID_SOCKET;
CString strMessage;strMessage.LoadString(IDS_CONNECTFAIL);
AfxMessageBox(strMessage);
return FALSE;

}

2009년 8월 17일 월요일

Dialog의 크기변화에 따른 Control 자동 Resize

출처 : http://www.codeguru.com/cpp/w-d/dislog/resizabledialogs/article.php/c1913/

Dialog Resize Helper
Rating:

Stephan Keil (view profile)
August 20, 2000

Environment: Windows 9x, Windows NT/2000

A DlgResizeHelper object helps you keeping a layout while resizing a dialog or - more generally - a window with child windows. For this class I was inspired by an article by John Keogh in DDJ 06/2000 ("Layout Management") and a look at Code Guru revealed some solutions as well. Nevertheless I find my solution more handy (of course ;-): it's C++ (in contrast to Keogh's code) and the class is not derived from CDialog (as most other solutions are) so it can be used with every window.
(continued)

In the dialog above you some controls want to tell you the meaning of life, but what is it? Now you can simply resize the dialog to read the desired info. Note that you can adjust the resize behaviour of the controls: the lists are resized in height and width, the edit and combo are just resized in width and the buttons stay fixed on the right side where the radio buttons belong to the lower list.

On initialization a DlgResizeHelper stores handles to all child windows of a parent window. Also you can optionally add other windows which shall be resized with the parent window. On resize the DlgResizeHelper resizes the child windows according to the size changes of the parent. By default a child is resized proportional to the parent's size but you can optionally fix the horizontal and/or vertical dimension/position of a child window. E.g. it's reasonable to fix the height of single line edit controls.

Usage (here e.g. with a dialog class):

1. Make your dialog resizable (give it a resizable border)

2. Add a DlgResizeHelper member to your dialog class:

#include "DlgResizeHelper.h"  class CMyDialog : public CDialog {  //...  DlgResizeHelper m_resizeHelper;  //... }; 

3. Initialize the resize helper in OnInitDialog():

BOOL CMyDialog::OnInitDialog() {  //...  m_resizeHelper.Init(m_hWnd);   // default behaviour is to resize sub windows proportional to the  // resize of the parent you can fix horizontal and/or vertical  // dimensions for some sub windows by either specifying the  // sub window by its hwnd:  m_resizeHelper.Fix(m_buttonCtrl,                     DlgResizeHelper::kLeft,                     DlgResizeHelper::kNoVFix);   // its item id:  m_resizeHelper.Fix(IDC_PRESS_ME,                     DlgResizeHelper::kWidth,                     DlgResizeHelper::kNoVFix);   // or all sub windows with a common class name (especially useful  // for single line edit controls)  m_resizeHelper.Fix("Edit",                     DlgResizeHelper::kNoHFix,                     DlgResizeHelper::kHeight);   //... } 

4. Tell the resize helper when the size has changed:

//... BEGIN_MESSAGE_MAP(CDlg_resizerDlg, CDialog)  //{{AFX_MSG_MAP(CDlg_resizerDlg)  //...  ON_WM_SIZE()  //...  //}}AFX_MSG_MAP END_MESSAGE_MAP()  void CMyDialog::OnSize(UINT nType, int cx, int cy) {  CDialog::OnSize(nType, cx, cy);  m_resizeHelper.OnSize(); } 

That's all. In most cases it is ok if the user enlarges a dialog, but shrinking it would destroy the layout. So you might choose to enforce a minimal dialog size by handling the WM_GETMINMAXINFO message (see demo software for an example).

The demo application is a dialog with a bunch of buttons. The name of the buttons reveal their fixed dimensions.

Downloads

Download demo project - 66 Kb
Download source - 3 Kb

COM DLL만으로 tlb파일 생성및 COM사용하기

출처 : http://thepassion.tistory.com/22

1. visual studio도구의 OLE View나 실행>oleview를 실행해서 oleviewer를 실행시킨다.
2. File>View TypeLib메뉴를 선택해 해당 COM dll혹은 COM exe를 Open한다.
3. 디스플레이되는 정보에서 Root로 표시되는 XXX(xxx x.x Type Library)를 클릭하면 오른쪽 윈도우에 idl파일을 생성해서 보여준다.
4. 해당 내용을 xxx.idl로 저장한다.
5. *.tlb파일 생성하기
방법1)
- Win32 Dynamic Linked Library프로젝트 생성해 빈프로젝트를 만든다.
- 4항 에서 저장한idl파일을 프로젝트에 포함한후 Build하면 *.tlb파일이 생성된다.
*** VC++의 Project>setting>midl탭에 MkTypLib commpatible항목이 체크되어있어야 한다.
방법2)
- 명령프롬프트 창에서 다음과 같이 입력해 tlb파일을 생성한다.
- C:\>midl /mktyplib203 xxx.idl
6. 해당 Com을 사용해야 하는 프로젝트에 tlb파일을 import한다.
방법1)
1)
#import "xxx.tlb"를 추가후 컴파일하면 xxx.tlh파일이 생성된다.
xxx.tlh파일을 열어보면, namespace와 CLSID, IID등의 정의 부분이 존재한다.

2)
최종적으로,
#import "xxx.tlb" named_guids
using namespace XXXX;
를 코드에 삽입한후 사용하면 된다.

방법2)MFC를 이용하는 경우
Ctrl+w를 눌러 클래스 위자드를 실행시킨후, New Class버튼을 눌러 From TypeLib를 선택한다.
5항에서 생성된 tlb파일을 선택하면, 해당 Com을 사용할수 있는 wrapper class를 자동으로 생성해 준다

Output 창에서 Todo List 보여주기

#define __STR__(x) #x
#define __CONST_TO_STR__(x) __STR__(x)
#define __FILE_AND_LINE__ __FILE__ "("__CONST_TO_STR__(__LINE__)")"
#define __TODO__ __FILE_AND_LINE__ " : TODO: "

을 미리 정의한후,

Code내에서

#pragma message( __TODO__ "Todo Test...") 를 입력한다.

Simple IE-like Menu and Toolbar

간혹 VC++6.0에서 작업한 File을 VC2008로 Conversion시켜서 작업해야할때가 있다. 메뉴나, Toolbar가 상당히 맘에 안드는경우에 적용하도록.

!! 아래의 사이트의 DownLoad 항목은 Unicode를 지원하지 않음. 첨부파일은 Unicode지원토록 수정완료.

출처 : http://www.codeguru.com/cpp/controls/toolbar/article.php/c5487/

1 Overview

This article was inspired by the Alpha WTL Sample application that I saw recently. I decided to do something similar, using the MFC library. Standard MFC applications are very out of date with their 16 colored toolbars and menus without images. There are some MFC extensions that implement Office- or Visual Studio-like control bars. They are pretty and very powerful, but just too complicated for most simple applications. Besides, they don't obey the standard Windows UI style. My idea was to create a simple interface based on Internet Explorer that implements features introduced in Windows XP and remains compatible with all OS versions since Windows 98.

The project consists of three classes:

CMenuBar: A toolbar that looks and acts exactly like a menu bar. It can be placed in a rebar control just like in Internet Explorer. It also draws icons next to menu items.

CAlphaImageList: A replacement for CImageList that supports images with an alpha channel introduced in Windows XP. It automatically generates hot and disabled images looking like those in Internet Explorer 6.

CAlphaToolBar: An extension of CToolBar that allows using alpha channel images.

Under Windows XP, this interface automatically uses either the 3D style or the new flat style (compared in the picture above). Under older OS versions it uses the traditional 3D style. Another feature introduced in Windows XP is images with alpha channel. The icons can have smoothed edges so that they look good on every background, dark or bright. This interface works correctly with images from 16 colors to 32-bit alpha channel bitmaps under all versions of Windows.

2 Using It in Your Applications

Note: The menu bar only works in SDI frame windows. It can't be used in dialog windows or in MDI frame windows.

Step 1: Add AlphaImageList.cpp, AlphaToolBar.cpp, and MenuBar.cpp with their corresponding headers to your project.

Step 2: Make sure that your application uses the Windows XP visual style. Copy the manifest.xml file to the res directory of your project and add the following line to YourApp.rc2:

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "res/manifest.xml"

Step 3: Ensure that Windows XP symbols will be included in your project. Add the following directive at the beginning of StdAfx.h or define it in your project settings:

#define _WIN32_WINNT 0x0501

You will need the new Platform SDK that includes Windows XP symbols.

Step 4: Put the following in your frame window header:

protected:  // control bar embedded members     CStatusBar    m_wndStatusBar;     CMenuBar      m_wndMenuBar;     CAlphaToolBar m_wndToolBar;     CReBar        m_wndReBar; 

Of course you may add any number of toolbars and dialog bars to the rebar control.

Step 5: Modify your frame window's OnCreate handler like in the example:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)         return -1;      GetMenu()->DestroyMenu();     SetMenu(NULL);      if (!m_wndToolBar.Create(this, AFX_IDW_TOOLBAR) ||         !m_wndToolBar.LoadToolBar(IDR_MAINFRAME, AILS_NEW))     {         TRACE0("Failed to create toolbar\n");         return -1;      // fail to create     }      if (!m_wndMenuBar.Create(this) ||         !m_wndMenuBar.LoadMenuBar(IDR_MAINFRAME, AILS_NEW))     {         TRACE0("Failed to create menubar\n");         return -1;      // fail to create     }      m_wndMenuBar.LoadToolBar(IDR_MAINFRAME);      if (!m_wndReBar.Create(this, RBS_BANDBORDERS,         WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS                  | CBRS_ALIGN_TOP)         || !m_wndReBar.AddBar(&m_wndMenuBar)         || !m_wndReBar.AddBar(&m_wndToolBar, NULL,                              (CBitmap*)NULL, RBBS_BREAK))     {         TRACE0("Failed to create rebar\n");         return -1;      // fail to create     }      if (!m_wndStatusBar.Create(this) ||         !m_wndStatusBar.SetIndicators(indicators,           sizeof(indicators)/sizeof(UINT)))     {         TRACE0("Failed to create status bar\n");         return -1;      // fail to create     }      return 0; } 

Step 6: Add the following message handlers to your frame window: PreTranslateMessage, WM_MENUCHAR, WM_SYSCOMMAND, WM_ACTIVATE, and WM_SETTINGCHANGE.

BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) {     if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam                       == VK_MENU)         m_wndMenuBar.SetPrefix(TRUE);     else if (pMsg->message == WM_KEYUP && pMsg->wParam                            == VK_MENU)         m_wndMenuBar.SetPrefix(FALSE);      return CFrameWnd::PreTranslateMessage(pMsg); }  LRESULT CMainFrame::OnMenuChar(UINT nChar, UINT nFlags,                                CMenu* pMenu) {     if (m_wndMenuBar.OpenMenu(nChar))         return -1;      return CFrameWnd::OnMenuChar(nChar, nFlags, pMenu); }  void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam) {     if (nID == SC_KEYMENU && m_wndMenuBar.OnKeyMenu(lParam))         return;      CFrameWnd::OnSysCommand(nID, lParam); }  void CMainFrame::OnActivate(UINT nState, CWnd* pWndOther,                             BOOL bMinimized) {     m_wndMenuBar.Activate(nState != WA_INACTIVE);      CFrameWnd::OnActivate(nState, pWndOther, bMinimized); }  void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) {     m_wndMenuBar.UpdateSettings();      CFrameWnd::OnSettingChange(uFlags, lpszSection); } 

2.1 Toolbar images

The CAlphaImageList class supports two styles of images:

AILS_OLD: The image list uses a 16-color bitmap and doesn't create the hot and disabled images. The toolbar looks like in old style applications. The default background color (RGB 192,192,192) is used as transparent. You can change it by modifying the following line in AlphaImageList.cpp:

#define AIL_TRANSPARENT   RGB(192,192,192)

To avoid some gray parts of buttons (like the disk label or the printer) being treated as transparent, I modified the original bitmap so that the magenta color is replaced by a slightly lighter gray (RGB 208,208,208), which is non-transparent. You can replace the Toolbar.bmp file with Toolbar4.bmp from the resources directory of the demo project. Before that, change the toolbar button size to 16x16 pixels.

AILD_NEW: The image list uses a 32-bit bitmap if comctl32.dll version 6 is detected or a 24-bit bitmap otherwise. You can use any number of colors in the toolbar bitmap. If the bitmap contains an alpha channel and the image list is 32-bit, the alpha channel is used as transparency information. Otherwise, the gray color (RGB 192,192,192) is transparent and all other colors are opaque.

You can create 32-bit bitmaps using Adobe Photoshop or a similar application. Even if the image has an alpha channel, you should use the gray color as the background so that the transparency is correct in previous OS versions—the only difference is that the icon edges won't be smooth in that case.

The resources directory of the demo project contains three versions of the new style toolbar bitmap: 8-bit, 24-bit, and 32-bit (with alpha channel). You can use whichever you want in your application. The bitmap was taken from the WTL sample application, with the background color changed to gray. The toolbar button size should be 16x16.

Note that Visual Studio will not let you edit the toolbar if the bitmap contains more than 256 colors. In that case, you will have to modify the resource file (YourApp.rc) by hand. The toolbar definition looks like this (16, 16 is the button size and IDR_MAINFRAME is the resource ID):

IDR_MAINFRAME TOOLBAR DISCARDABLE  16, 16 BEGIN     BUTTON      ID_FILE_NEW     BUTTON      ID_FILE_OPEN     BUTTON      ID_FILE_SAVE     SEPARATOR     BUTTON      ID_EDIT_CUT     ... END 

2.2 Menu resource

CMenuBar contains the following functions to load data from resources:

BOOL LoadMenuBar(UINT nID, int nStyle=AILS_OLD)

Load a menu resource. The nStyle parameter specifies the image list style (see above). You may call this function multiple times to replace the previous menu. The menu bar will automatically resize inside a rebar if needed. All images will be discarded.

BOOL LoadToolBar(UINT nID)

Load images from the bitmap resource and assign them to menu items with the same command IDs as in the toolbar resource. You may add multiple toolbars to a menu. You can create a separate toolbar resource that contains images for menu items, or use the default toolbar.

The menu bar assumes that the size of all images is 16x16 pixels. You can change this by editing the following lines in MenuBar.cpp:

#define MB_CX_ICON  16 #define MB_CY_ICON  16 

2.3 Popup menus

CMenuBar also provides support for displaying context menus with the correct visual style and images. Put all popup menus in one resource and call the following function to load it:

BOOL LoadPopupMenu(UINT nID)

This menu will automatically use the same images as the window menu. There are two functions to display popup menus:

void TrackPopup(int nIndex, CPoint ptPos) void TrackPopup(LPCSTR lpszName, CPoint ptPos) 

The first one uses the menu index; the second one uses the name of the menu, which may be more comfortable if your application uses many context menus. The ptPos is the menu position in screen coordinates.

Note: If you don't load a separate popup menu, the window menu will be used by default.

3 Final Notes

I found a bug in MFC 6 that caused the edit view to be incorrectly placed in the window, so that it covers a part of the rebar. The CEditView::CalcWindowRect should be replaced with CView::CalcWindowRect to fix this. Also, the edit view doesn't load and save the text correctly if comctl32.dll version 6 is used.

Implementing support for MDI applications is possible, but quite difficult. Anyway, the MDI architecture is not comfortable and out of date; check out my last article (Multithreaded SDI Applications) for a different solution. There are a lot of things that could be done, such as support for chevrons, popup buttons, and so forth. However, I tried to keep this code small, simple, and yet useful for most purposes.

Visit the author's home page at http://www.mimec.w.pl.

Downloads

Download demo project - 49 Kb
Download source - 15 Kb

Ultimate Toolbox

Ultimate Toolbox

그간 UI작업하느라 고생했는데.. 구세주를 이제 찾다니.

http://www.codeproject.com/KB/MFC/UltimateToolbox.aspx

CDateTimeCtrl 의 Color 변환

간혹 CDateTimeCtrl의 색상을 변환할때가 있다.

달력 Control의 경우에는 SetMonthCalColor 함수를 사용하여 색상을 변경할수있지만,

DateTimePicker의 경우에는 Background및 Text의 색상변환이 그다지 쉽지는 않다.

여기저기 검색을 해본결과, 특히 Text의 색상변환은 거의 없어서 약간의 꽁수로..

저처럼 헤딩하지 마시고 잘 쓰시게~~

Custom UI에대한 고려

간혹가다가 UI에대한 Subclass 를 하는경우가 있다.

특히 OnPaint에대한 코드를 빈공백으로 하면 문제가 발생할수있음.. !!!

CWnd::PreSubclassWindow 에 관하여

간혹 Control을 사용하면서 값에대한 초기화가 필요한 경우가 있다..

물론 Construct에서 입력을 해야하는경우도 있지만, 해당 control을 생성한후, 직접적으로 적용해야 하는 초기화,

예를 들어 Button에 SetFont의 함수를 적용할려면 Construct에서 호출할수없다. Control이 생성된이후에야 적용이 된다.

그리하여, WM_CREATE를 사용하여 작업을 하면, 진입하지 않는 희안한 경우가 생긴다.

그 이유는. DialogBox의 DDX_Control특성상 Subclass를 통해 Control을 사용하기 때문이다.

그렇다면 어떻게 해결을 해야하는지를 알아보면,

virtual Type의 CWnd::PreSubclassWindow() 함수가 제공이된다.

이 함수에대한 overloading을 통해 제어하면 끝~~~~

AnalogGuage

-. 참고 :http://www.codeproject.com/KB/GDI-plus/AquaGauge.aspx

AnalogGuage를 사용할 필요가 있어 이리저리 뒤져보다가 맘에 드는것이 있는데.

dot net버젼이라. C++ version으로 porting 했습니다.. 그리고, 추가적인 기능들을 넣었습니다.

_ASSERTE macro

잘 알다시피, ASSERT는 너무나도 자주쓰는 Debug용 macro다. 이번에 소개할것은 ASSERT의 확장형인 ASSERTE 및

debugger's output 창에 assert 문구를 삽입하는것을 소개한다.

추가로, _CrtSetReportMode를 이용하여 File로 Log를 남길수도 있다. 자세한것은 MSDN 참고

#ifndef _MYASSERTE
#ifndef _CRT_SET_REPORT_MODE
#define _CRT_SET_REPORT_MODE
#define _MYASSERTE(expr) \
_CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_DEBUG|_CRTDBG_MODE_WNDW);\

(void) ((!!(expr)) || \
(1 != _CrtDbgReportW(_CRT_ASSERT, _CRT_WIDE(__FILE__), __LINE__, _CRT_WIDE(__FUNCTION__), _CRT_WIDE(#expr))) || \
(_CrtDbgBreak(), 0))
#else
#define _MYASSERTE(expr,msg) \\
(void) ((!!(expr)) || \
(1 != _CrtDbgReportW(_CRT_ASSERT, _CRT_WIDE(__FILE__), __LINE__, _CRT_WIDE(__FUNCTION__), _CRT_WIDE(#expr))) || \
(_CrtDbgBreak(), 0))
#endif
#endif

문자열에 _T() 넣기

MFC에서 Unicode기반의 작업을 하다보면, 문자열을 넣을때 귀찮은 경우가 많다.

일반적으로 _T("냠냠이") 이런식으로 적용을 하는데, 매번 _T()를 넣는다는것이 나의 귀차니즘을 자극시키는....

그래서 Macro를 작성하여 적용하는것이 어떨까 한다.

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' -.선택한 문자열을 검색하여 문자열 앞뒤에 _T()를 삽입한다.
' 09.01.19 pumpguy create
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub Do_TMacro()
Dim objStartPt As EditPoint
Dim szLineData As String
Dim point As EditPoint
Dim nColPos As Integer
Dim szNewData As String
Dim bFirst As Boolean
Dim ch As String

bFirst = True
With DTE.ActiveDocument.Selection
szLineData = .Text
For i = 1 To szLineData.Length
Select Case Mid(szLineData, i, 1)
Case Chr(34)
If bFirst Then
szNewData = szNewData + "_T("
szNewData = szNewData + Mid(szLineData, i, 1)
bFirst = False
Else
szNewData = szNewData + Mid(szLineData, i, 1)
szNewData = szNewData + ")"
bFirst = True
End If
Case Chr(92)
szNewData = szNewData + Mid(szLineData, i, 2)
i = i + 1
Case Else
szNewData = szNewData + Mid(szLineData, i, 1)

End Select
Next i
.Text = szNewData
End With
End Sub

사용법은 해당 Macro를 작성한후, Tools->Customize 를 통해 나온 DialogBox에서 Keyboard Button을 눌러 단축키와 Macro를 연결하면 된다.

Bug : 2개이상의 Line을 Select시 두번째 줄부터 열이 안맞는다~ ㅎㅎㅎ 정신건강상 한Line씩만 선택해서 작업하시길.

Memory Leak Check Tip

MFC를 쓰면서 Memory Leak에 대한 Check부분이 상당히 편하다.

일반적으로

Dumping objects -> xxx.cpp {91} normal block at ... 식의 File명이 나오는데,

간혹 File명이 안나오고 , Memory Block만 ( {91} ) 나오는 경우엔 _CRTXXX 함수들을 통해 해당 Memory를 Alloc하는 곳을

찿아야 한다.. 근데, 좀더 쉬운 방법이 있어 소개를 시켜주면,

Program의 진입점(MFC의 경우에는 WinApp::InitInstance, Console에서는 main)의 첫줄에 아래와 같은 함수를 호출하면 된다.

AfxSetAllocStop(91) --> 91번째 Alloc시의 Application이 Stop되어 해당 위치를 편하게 찾을수있다.

Glass Button

출처 : http://www.codeproject.com/KB/buttons/glassbutton.aspx

Glass 효과가 나는 Btn이 있어서 링크를 걸어놓는다.

해당 소스는 C#으로 작성되었으며, MFC 사용자는 첨부된 File중 MFC Host App Project를 Compile 하도록..

물론, 맨처음에 GlassButton을 Compile후 다른 Sample Project를 사용하시길...

InstallAware - Unicode 사용하기

출처 : InstallAware 도움말, http://www.installaware.com/blog/?p=19

InstallAware를 사용하면서, 문자열에대한 기본적인 속성이 ANSI로 되어있다. ==> File명및 Folder명중 한글이나 기타 Unicode가 들어가

면 , Install시 설치가 안된다.

이것을 Unicode를 지원하게 하는 방법이 있는데..

1. Pre-Defined Compiler Variables중에서

  • CODEPAGE: If unspecified, the recommended English codepage of 1252 is used. Other suggested values are 65000 for UTF-7 unicode and 65001 for UTF-8 unicode, or 0 for codepage neutral. Change this value if your setup installs or otherwise makes use of files with accented or non-ASCII locale-specific characters in their names. Ensure this codepage matches the codepage of your current host system to prevent data corruption in your MSI databases and to ensure the correct codepage is used on target systems, thus preventing issues with incorrectly interpreted file names leading to failures when finding files at install-time. Using unicode codepages will render your setups unworkable on Windows 9X operating systems (Windows 95, Windows 98, and Windows ME); however it will ensure the broadest compatibility on Windows NT operating systems (Windows NT 4, Windows 2000, Windows XP, Server 2003, Windows Vista, Server 2008, and Windows 7).
  • CodePage에 관련된 부분을 변경하면 된다.

    2. Pre-Define값을 바꾸는 방법은

    Hello everyone, I hope you’ve all been well!

    This post’s topic: How to customize your setup at build time. This could be used for different products, when only very few things change between them, and having a unique setup project for each one turns into a major copy and clone nightmare. It’s really a quite common scenario to have similar products using similar setup routines. At InstallAware, we actually ship a single installer that contains all four of our product editions - allowing users to choose at runtime which version they want to install. We might cover that in a later post; for now we’ll look at how to customize your installations at build time - emitting multiple “flavors” of a setup, if you will. This is where Compiler Variables come into play.

    Compiler Variables are defined inside the Project Options window. To bring up this window, click the Project Settings button, found inside the Manage group of the Design tab.

    Choose the Compiler Variables section and you’ll see three buttons, Add, Edit and Delete. This is where you define and set the initial values of your Compiler Variables. These variables are accessed using the #COMPILER_VARIABLE_NAME# format inside your MSIcode script. You may use these variables anywhere inside your script. Even MSIcode command fields which do not ordinarily accept variables will take compiler variables, since compiler variable values are “burnt-in” at build-time, and do not change at runtime.

    In addition to replacing literals with values injected at build time, another use of compiler variables is to conditionally include/exclude parts of your MSIcode script. Use the Compiler Variable If, Compiler Variable Else and Compiler Variable End MSIcode commands to include/exclude parts of your setup project at build time. This adds a lot of flexibility to how you can build setups at runtime - you can take out whole blocks of MSIcode script, completely changing your setup logic and files - all at build time, and without needing to use complex automation.

    Here’s a short list of what you can customize with compiler variables, among other things:

    1. Product name
    2. Product version
    3. Product code
    4. Files being installed
    5. Features being built

    Take look at the code below to see what I mean:

    As you can see, one of my compiler variables is “MYPRODUCT” and its defined/initialized on the Compiler Variables section of the Project Options window. The above code builds some files and features if the compiler variable “PRODVERSION” is equal to “Enterprise” but excludes one file if the compiler variable “SUBVERSION” is not equal to “Full”.

    You might also want to take a look at the pre-defined compiler variables that already exist in InstallAware. There are two kinds of pre-defined variables - pre-defined compiler variables and pre-defined script/runtime variables - so don’t get confused between the two. Both of these pre-defined variable kinds come in real handy for lots of things, like figuring out the execution path of your setup. I’d definitely encourage you to take a look at them. Just search for pre-defined variables and pre-defined compiler variablesin the help index.

    My favorite compiler variables are the following:

    1. LOADOLDDATA: Instructs the setup engine to migrate feature selections from older versions.
    2. PROJDIR: Resolves to the project directory on your system.
    3. LOADOLDDATA: Instructs setup to change the way in which localizations are applied at runtime (see the help file for details).
    4. BUILDMODE: Resolves to CD, SFX, WEB, or PATCH based on your setup build mode.
    5. TITLE: Resolves to the name of the setup project.

    Thank you,

    Panagiotis Kefalidis
    Software Design Team Lead
    InstallAware Software Corporation