CAB 파일을 만들다 보면 여러개가 생성이 되어 한번에 동시에 설치하지 못하는 경우가
발생한다. 물론 사용자가 일일히 CAB 파일을 클릭해서 설치하면 되지만
여러개 이라면 쉽지 않은일..
이것을 처리하기 위한 배치 파일을 만들어 보자.
copy xxxabc.CAB Temp1.CAB
wceload Temp1.CAB
여기서 핵심은 wceload.
이 프로그램을 이용해 CAB을 설치하는것이다.
출처 : 배소영(hobak2)
쉽게 연상할수 잇는 차이점은 DLL 내에 MFC 의 함수들을 싣을 것인지 아닐지를 결정하는 내용이라는 것이다. 즉 만들 DLL 안에 MFC의 각종 실행 로직이 들어가게 디면 Static 아니면 Shared 가 되는 것이다.
프로그램을 만들때는 큰 차이가 없다가, 실제 릴리즈 할때, 이 프로그램이 실행되는 환경에,
해당하는 버젼의 MFC.DLL이 없으면 실행이 안된다.
하지만, Shared 인경우 해당하는 프로그램이 상당히 Light 해진다. 즉 실행 모듈을 싫지 않기 때문에 얻어지는 최대의 장점이다. MFC ㅁ모듈을 사용하는 양에 따라 달라지지만, 대개 100K 짜리를 기준으로 한다면 MFC를 Shared 하게 되면 70~80%의 경감을 가져온다.
하지만, Shared 에 또다른 문제가 있으니, 그것이 바로 Resouce 문제다.
Shared를 택하게 되면 이 DLL을 부르는 Main 프로그램과 Resouce를 겹쳐서 사용하게 되는 문제가 있다. 그래서 DLL내의 리소스를 사용하려면, 현재 사용중인 HINSTANCE를 DLL쪽으로 맞추어 주어야 한다.
현재 Main의 HINSTANCE를 get 해와서 저장하고, DLL의 HINSTANCE를 현재 HINSTANCE로 변경해서 DLL내의 리소스를 사용하고 난뒤, 다시 저장해 놓았던 Main의 HINSTANCE를 현재 HINSTANCE로 변경해야 한다.
그러나 Static으로 하게되면 이 리소스 마저 분리되는 것 같다. 아무런 문제없이 사용가능하게 된다.
어떤것을 사용할지는 상황에 맞게 해야 겠지만, 일단, FlexBuilder에서는 그냥 Static을 우겨야 겠다.
보통 텍스트를 쓸때, 배경 색과 텍스트의 배경색이 틀려지면,
이상하게 글자 주변에만 기묘한 색이 되어 배경색과 따로 논다.
즉 글자만 색이 달라야 하는데, 글자를 기준으로 글자 크기만한
사각형이 다른 색이라면 정마리지 보기 싫어지게 된다.
그래서 이를 방지하기 위해 SetBkMode라는 메소드를 이용해,
SetBkMode(TRANSPARENT) 를 호출한다.
그러나 이것을 OnCtrlColor에서 사용하면 기묘한 결과를 얻어 낸다.
HBRUSH CTextCtrl::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
if(pWnd == m_pEdit) {
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(m_fontColor);
return (HBRUSH)m_brush;
}
return hbr;
}
위의 내용이 바로 그 내용인데, 이렇게 해도 일단은 원하는 기능은 얻기는 한다.
그러나 문제가 있다. 스크롤이 되거나 새로운 글자가 입력될때, 이전 글자가 지워지지 않고
계속 겹쳐져 그려지는 문제이다. 이는 위의 Mode가 TRANSPARENT 여서 계속 겹쳐져서
그려지는 것 같다.
이를....
pDC->SetBkMode(TRANSPARENT);
->
pDC->SetBkColor(m_backColor);
로 변경해 준다.
이렇게 하면 비록 투명은 아니지만 그와 같은 효과를 얻게 된다. 더욱이 이전에 발생한 문제가
해결된다.
이 문제는 글자를 새롭게 입력을 받는 에디트 컨트롤을 child로 잡게 된 경우에 발생하는 문제다.
NT류 윈도우에서는 unicode로 하지 않으면 이상하게 edit control에 한글이
입력시마다 깨져서 나오져.. 근데 우낀건 paste로 한글을 쓰면 써지더군요..
그걸 window98에 가서 해보면 잘되져.. 근데 모두 98만 쓰는것두 아니고
그렇다고 unicode로 하자니 98에서 안되고...
어디가도 해결법을 찾을수 없어서 고민고민하다가 이상한 방식으로 해결했습니다.
뭐 근본적인 문제는 뭔지 알수 없지만...
방법은 edit control을 서브클래싱해서 WM_IME_CHAR메세지를 처리해 줍니다.
LRESULT OnImeChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
static char kk[3];
kk[0] = (char) (wParam >> 8);
if(kk[0]==0x00)
{
bHandled=FALSE;
return 0;
}
kk[1] = (char) wParam & 0xff;
SendDlgItemMessage(IDC_MYEDIT, EM_SETSEL, 0, -1);
SendDlgItemMessage(IDC_MYEDIT, EM_SETSEL, -1, 0);
SendDlgItemMessage(IDC_MYEDIT, EM_REPLACESEL, FALSE, (LPARAM) kk);
return 0;
}
그럼 됩니다. ㅋㅋ
참고로 ATL에서 서브클래싱하는것도 히한하죠..
생성자에서..
CContainedWindow m_EditCtrl;
CMyClass() : m_EditCtrl(_T("EDIT"), this, 1)
{
m_bWindowOnly = TRUE;
m_Total=0;
CalcExtent(m_sizeExtent);
m_sClient=0;
}
메세지맵에서..
BEGIN_MSG_MAP(CMyClass)
CHAIN_MSG_MAP(CComCompositeControl<CMyClass>)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
...
ALT_MSG_MAP(1)
MESSAGE_HANDLER(WM_IME_CHAR, OnImeChar)
BEGIN_MSG_MAP(CMyClass)
...
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_EditCtrl.SubclassWindow(GetDlgItem(IDC_MYEDIT));
....
제가 별로 아는게 없어서 되는대로 했는데
더 괞찮게 하는 방법이 있으면 답변달아주세여........
tab tab되나????
다중 상속을 받은 클래스를 생성하는 것 만큼
삭제하는것이 쉽지 않다.
이 문제의 발생 원인은 다중 상속에서 인해,
Construct 와 Destruct 의 역할 분배에서 생기는 문제 인듯 싶다.
하지만, 이는 정확한 정보는 아니고 오로지 개인적인 짐작에 불과하다.
하지만 현재 제작중에 발생한 문제이기 때문에, 이 문제를 언급한다.
class A : public CA, public CB {};
가 있다.
이를 생성하기 위해 new A 를 해서 CB *pB 에다 담는다.
CB *pB = new A();
그후에 이를 지우려 하는데, Assert 에러를 낸다.
그 이유가 CA로써 지우는 건지 CB로써 지우는건지 명확치 않아서 발생하는 것 같았다.
그래서 약간 변형을 가했다.
delete (CA *)pB;
이렇게 지우자 문제가 사라졌다.
게다가, CB에서는 Construct와 Destruct가 없는 상황이기 때문에, 더욱 이렇게 할 수 밖에 없는듯 싶다.
이 관계를 잘 파악해야 하겠다.
기존에는 화살표를 직접 그려야 되기 때문에,
삼각함수를 이용해 삼각형 좌표를 얻어와 그리게 되어있다.
그러나 GDI+에서는 Pen 객체에서 Line Caps 라는 것을 지원한다.
Pen pen(Color(255, 0, 0, 255), 8);
stat = pen.SetStartCap(LineCapArrowAnchor);
stat = pen.SetEndCap(LineCapRoundAnchor);
stat = graphics.DrawLine(&pen, 20, 175, 300, 175);
소스를 보면 알겠지만, 펜 자체의 형태를 구성해서 Line을 그릴때,
첫점과 끝점에 내용을 채워 넣을 수 있다. 다양한 형태의 Line 끝점을 설정하게 되는데, 그 나열자들을 보면..
LineCapFlat
라인 끝의 모양을 단순한 형태로 끝을 마무리 한다.
LineCapSquare
라인 끝 모양을 정사각형의 모양으로 마무리한다. 정사각형의 넓이와 높이는 라인의 넓이에서 결정된다.
LineCapRound
라인 끝을 둥글게 마무리한다. 라인의 반지름은 라인의 넓이에서 결정된다.
LineCapTriangle
라인 끝을 삼각형으로 만든다. 삼각형의 중심 높이는 라인의 넓이에서 결정된다.
LineCapNoAnchor
라인 끝에 아무것도 붙이지 않는다.
LineCapSquareAnchor
라인 끝에 정사각형의 모양을 붙인다. 이 때의 높이와 넓이는 라인의 넓이에 영향을 받게 된다.
LineCapRoundAnchor
라인 끝애 원을 붙인다. 원의 반지름은 라인의 넓이에 영향을 받는다.
LineCapDiamondAnchor
라인 끝에 다이어몬드 모양을 붙인다. 다이어몬드는 정사각형에서 45도 돌려서 구성한 형태를 의미한다. 정사각형 처럼 넓이는 라인의 넓이에 영향을 받게 된다. 단 정사각형에서 보다 라인의 넓이 보다 더 넓게 차지하게 된다.
LineCapArrowAnchor
라인 끝에 화살표를 붙인다.
LineCapCustom
라인 끝 자락에 사용자 정의형을 붙인다.
여기서 LineCapArrowAnchor를 사용하게 되면 화살표를 직접 만들어 붙일 필요가 없고 GDI+에서 알아서 붙여주게 된다 .
GDI+ 란 class 기준으로 제작한 C/C++ 프로그래머들을 위한 API이다.
제작하는 방법은 다양하지만, MFC 기반으로 제작을 하게 되지만, API
함수를 부르는 형태로 구성하기도 한다.
MFC7.0 에서는 자동적으로 부르게 되어 있지만, MFC4.2에서는 아직
본격적 지원은 하지 않는다.
GDI+ 는 WindowsXP와 Window2003에서는 자체적으로 포함되어 있으며, Windows NT 4.0 SP6, Windows 2000, Window98/ME 등에서는 설치를 해서 처리하게 된다. 실행시에는 System 폴더 안에, Gdiplus.dll 이 있으면 된다.
GDI+는 크게 3가지 부분으로 구성되어 있다.
- 2D Vector graphic
점/선/상자/색칠 등의 기능을 사용하는 기능으로 일반적인 그림 그리기의 기능을 의미하게 된다.
- 이미지 처리
각종 디지털 사진들의 처리라든가, 특정 컴포넌트에서 표현하기 힘든 그리기 기능들을 적용할 때 이용되는 기술이다.
- 글자처리
폰트에 관련되어 출력하게 되는 처리에 대한 기술
이 GDI+ 의 구성은 40여개의 클래스와 50여개의 나열자, 6개의 구조체로 구성된다. 그 중 Class로 구성되지 않은 함수도 존재한다.
보통 Graphics 라는 클래스에서 시작되어 구성되어 있다. 그러나 몇개의 클래스등을 다목적으로 이용하기 위해 그 외의 형태로 구성되기 도 한다.
그리고 클래스에 포함안된 함수가 있는데, GdiplusStartup / GdiplusShutdown이 바로 그 둘이다.
기존 GDI에서 추가된 사항은
Gradient Brushs 기능, Cardinal Splines 기능, 독립적 Path Objects, Transformations 와 Matrix Object, Scalable Regions과 다양한 이미지 파일의 지원등이다.
그리고 기존 GDI객체를 사용하는데서 오는 변경을 몇가지 해줘야 하는데,
GDI+에서는 Graphics 객체를 사용하게 된다. 이를 적용하려면, HDC를 전해 주는 것으로 해결하게 된다 . 즉 Graphics 객체에게 HDC를 건네주어 처리하는 것이다.