[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

여러사람이 다양한 지역에서 같은 code branch를 가지고 작업할 경우, 특정인이 check-in한 code가 branch전체를 망치는 경우가 발생한다. build가 안될 수도 있고, program running초기에 비정상 동작으로 test자체가 불가능할 수도 있다. 한국과 영국 두 나라 개발자들이 같이 일을 하고 있는 상황을 생각해 보면, 한국인 개발자 누군가의 check-in 으로 인하여 branch가 전체가 망가지고 나서, 한국 사람들이 다 퇴근하면, 영국에서는 다음날 한국 사람이 출근할 때까지, 시차를 생각하면, 영국사람 입장에서는 working time내내, 아무일도 할 수 없게 된다. 물론, branch에 submit하는 개개인은 본인의 local pc에서 test한 후 정상 동작하는 것을 확인하고 branch에 check-in하겠지만, 개개인 local에 항상 최신 revision의 code를 가지고 있지는 않기 때문에 (항상 최신 revision의 code를 local에 유지하는 것은 상당한 overhead를 수반하기 때문에 이를 강제할 수는 없다. - 만약 이를 강제한다면, 여러사람이 일할 경우에는 sync받고 build하는 것 이외의 다른 일은 거의 할 수 없을 수도 있다.) 이전에 다른사람이 check-in한 code와 충돌해서 이런 현상이 벌어질 수도 있다.

그렇다면 이런 문제를 어떻게 해결할 수 있을까?
나는 이런 방법을 생각해 본다.

해당 branch에서 일하는 개발자들은 항상 자신이 일하는 office의 local time으로 오전, 9시~10시(출근하자마자) 사이에만 branch에 submit하도록 한다. 이렇게 하면, 그 날 하루동안 같은 time zone에 있는 여러 개발자들이 이 branch를 검증할 수 있는 시간이 생기고, branch에서 발생한 문제점을 check-in한 사람이 퇴근하기 전에 발견할 확률이 높아진다.

음.. 실제로 적용해 본적이 없으니... 효과는 잘...-_-;

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

We should not access memory address directly to read the value.

For example,

Int8* pt;
malloc(pData, 6);
pt = pData;
*pt = length;
pt++;
*pt = width;
pt++
*pt = (int)size; // ---(*)

This may create unexpected result due to data align. See (*). At (*), address of 'pt' is not 4-byte-aligned. But, it tries to write 4-byte-data (integer value). In this case, result may be compiler or target architecture dependent - usually, 'size' will be written at 4-byte-aligned-address.
Programmer who wrote above code may intent to make following memory state.

pData : [length(1 byte)][width(1 byte)][size(4 bytes]

But, usually, this may create following or undefined result.

pData : [length(1 byte)][width(1 byte)][padding(2 bytes)][size(4 bytes)]

So, we should not use like above(accessing memory directly). We can use 'struct' instead.
But, use 'memcpy' if above way is really needed.

(*) ==> memcpy(pt, &size, sizeof(size));

We should always keep it mind that data is aligned. So, directly accessing memory address to read or write data always has risk of compatibility with align.

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

Let's remind about endianness.

big-endian : most significant byte first.
little-endian : least significant byte first.

How about following code?

UINT16 b;
UINT8* p;
p = &b;
b = 0xABCD;
printf("%x, %x\n", p[0], p[1]);

This make different result according to endianness.

LE : CD, AB
BE : AB, CD

So, avoid kind of coding!

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

#define STORE_LE16(bUFF,nUM) ( ((bUFF)[1] = (UINT8) ((nUM)>>8)), \

                              ((bUFF)[0] = (UINT8) (nUM)) )

#define STORE_LE32(bUFF,nUM) ( ((bUFF)[3] = (UINT8) ((nUM)>>24)),    \
                              ((bUFF)[2] = (UINT8) ((nUM)>>16)),     \
                              ((bUFF)[1] = (UINT8) ((nUM)>>8)),      \
                              ((bUFF)[0] = (UINT8) (nUM)) )

/* Store value into a bUFFer in Big Endian format */
#define STORE_BE16(bUFF,nUM) ( ((bUFF)[0] = (UINT8) ((nUM)>>8)),     \
                              ((bUFF)[1] = (UINT8) (nUM)) )

#define STORE_BE32(bUFF,nUM) ( ((bUFF)[0] = (UINT8) ((nUM)>>24)),    \
                              ((bUFF)[1] = (UINT8) ((nUM)>>16)),     \
                              ((bUFF)[2] = (UINT8) ((nUM)>>8)),      \
                              ((bUFF)[3] = (UINT8) (nUM)) )

/* Little Endian to Host integer format conversion macros */
#define LEtoHost16(ptr)  (U16)( ((U16) *((U8*)(ptr)+1) << 8) | \
                                ((U16) *((U8*)(ptr))) )

#define LEtoHost32(ptr)  (U32)( ((U32) *((U8*)(ptr)+3) << 24) | \
                                ((U32) *((U8*)(ptr)+2) << 16) | \
                                ((U32) *((U8*)(ptr)+1) << 8)  | \
                                ((U32) *((U8*)(ptr))) )

/* Big Endian to Host integer format conversion macros */
#define BEtoHost16(ptr)  (U16)( ((U16) *((U8*)(ptr)) << 8) | \
                                ((U16) *((U8*)(ptr)+1)) )

#define BEtoHost32(ptr)  (U32)( ((U32) *((U8*)(ptr)) << 24)   | \
                                ((U32) *((U8*)(ptr)+1) << 16) | \
                                ((U32) *((U8*)(ptr)+2) << 8)  | \
                                ((U32) *((U8*)(ptr)+3)) )

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

* Making Blended & Clink-Through window

We can use following window style option at CreateWindowEx().
WS_EX_TRANSPARENT -> click-though
WS_EX_LAYERED -> alpha-blended window.

We can changne configuration in runtime by using following API.

SetLayeredWindowAttributes(...)
: Layered window's attributes (Alpha value, Transparet color etc) can be changed.

SetWindowLong(...)
: Window의 Ex Style can be changed. We can set or clear "Click-Through" by setting or clearing WS_EX_TRANSPARENT attributes.

* We can remove menu

by set 'lpszMenuName' as 'NULL' at 'WNDCLASSEX' structure when 'CreateWindowEx' is called.

* We can change initial background color of Window

by creating brush of preferred color at 'hbrBackground'.

* We can remove 'titlebar' and 'boarder'

by set 'dwStype' parameter as 'WS_POPUP' style.

* (Issue) Maximized window covers Taskbar!

We can resolve this issue by using 'WM_GETMINMAXINFO' and 'SystemParametersInfo/SPI_GETWORKAREA'.
('WM_GETMINMAXINFO' is sent when Window is moved or Window's size is changed.)

Let's put following code in the handler of 'WM_GETMINMAXINFO'.

MINMAXINFO* pi = (MINMAXINFO*)lParam;
RECT        r;
SystemParametersInfo(SPI_GETWORKAREA, 0, &r,0);
memset(pi, 0x00, sizeof(MINMAXINFO));
pi->ptMaxSize.x = r.right - r.left;
pi->ptMaxSize.y = r.bottom - r.top;
pi->ptMaxPosition.x = r.left;
pi->ptMaxPosition.y = r.top;

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

Win32에서 IME가 Active되어 있으면, 즉 Imm context가 window handle에 associate되어 있고, 한글 입력모드에서 입력을 하고 있으면, WM_KEYDOWN의 wParam이 VK code가 올라 오지 않고, VK_PROCESSKEY가 올라온다. 즉 Imm이 해당 key를 processing하고 있다는 뜻이다. 여기서 어떻게 원래의 Key code를 얻어 올 수 있을까?

MSDN을 참조하면, "mmGetVirtualKey()"를 쓰면 된다고 하는데, 막상 써 보면, VK_PROCESSKEY가 그대로 return된다. 웹을 더 찾아보면, TranslateMessage를 호출하기 전에 사용하면 된다고 하는데, 안해 봐서 모르겠고, 또 그렇게 하기도 힘들다.

이럴때는 약간은 portability와 compatibility가 희생해서, scan code를 사용하는 방법이 있다.
몇몇 platform의 경우, (Embedded환경은 특히...) scan code가 전부 0으로 올라오는 경우도 있어서 100% portability가 떨어지긴 하나 어차피 100% portable은 존재하지 않으니까... :-)

scan code는 WM_KEYDOWN message의 lParam의 16~23 bit (8bit)인데, 이를 "MapVirtualKey()"함수를 사용해서 virtual key code를 얻을 수 있다.
뭐 일단 얼마나 portability가 희생되는지는 모르겠으나, 어느정도 잘 동작하는 것은 확인했다. 이 방법을 사용하는 것도 괜찮겠다.

'Domain > Win32' 카테고리의 다른 글

[Win32] Function Calling Convention  (0) 2008.12.03
[Win32][Tips] Creating Window...  (0) 2007.06.27
[Win32] 한글 입력하기  (0) 2007.06.23
[Tips] Cross-Compiling on Windows for Linux  (0) 2007.06.20
[Tips] cygwin 'make' issue  (0) 2007.06.13

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

"WM_IME_COMPOSITION" 을 사용해야 한다.
뭐 MSDN을 찾아보면 관련 함수도 많이 나오고 설명도 많이 나오니 패스.
Font를 찍을 때는 TrueType의 경우, 그냥 GetWidth32W (32Bit 환경)을 써서 font width를 계산하면 된다.

몇 가지 주의할 점만 짚어 보겠다.
먼저 조합도중 Space입력.
이 넘이 상당히 많은 것을 자동으로 해 주어서 편하긴 한데, Asian국가중 힘 없는 한글은 상당히 무시되어 있다. ㅜ.ㅜ
젤 큰 문제는, 한글 조합도중 'Space'를 누르면, space가 Keycode로 올라와야 하는데, 이 Space는 그냥 "VK_PROCESSKEY"로 올라오고, "WM_IMM_COMPOSITION"에는 result로 space가 입력되기 전까지 조합되었던 글자가 올라온다. 즉, "WM_IME_COMPOSITION"만을 이용해서 한글 입력기를 만들게 되면, '가'를 입력하고(조합중) space를 치면, '가 '가 아니라 '가' 가 찍힌다. (Space가 나타나지 않는다.)
이를 처리해야 한다.!! (사실 일본어나 중국어의 경우 space는 character table을 보여주는 key로 사용되는 듯 하다. 그렇지만, 한글에는 그게 필요없으니.. MS한테 무시당했다...-_-;)

'Domain > Win32' 카테고리의 다른 글

[Win32][Tips] Creating Window...  (0) 2007.06.27
[Win32] IME Active중 VK Code얻기  (0) 2007.06.25
[Tips] Cross-Compiling on Windows for Linux  (0) 2007.06.20
[Tips] cygwin 'make' issue  (0) 2007.06.13
[VC][Tips] 2005 express  (0) 2006.04.12

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

Have you ever wanted to compile Linux binaries under Windows? This is how it

happens:
1. Get Cygwin setup.exe: http://www.cygwin.com/
1.1. Run setup.exe and continue to package selection list.
1.2. Under Devel catagory select tools you need for compiling your source. For example 'GNU make'.
1.3. Finish installing.

2. Get linux cross-compilers for cygwin:
"cygwin-gcc-linux.tar.bz2" (68.2 Mb). md5sum: 340e91a346f5bb17e660db10e43005b8
These compilers are made with crosstool 0.28-rc37. This package contains:
gcc-3.3.4 and gcc-2.95.3 for i386 (glibc 2.1.3) and gcc-3.3.3 for amd64
(glibc 2.3.2).

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

Note! There is now newer version of GCC avaible with glibc 2.3.2:
"cygwin-gcc-3.3.6-glibc-2.3.2-linux.tar.bz2 (i386, x86_64)".
2.1. Copy 'cygwin-gcc-linux.tar.bz2' to 'c:\cygwin' or install directory which you selected in setup.exe.
2.2. Open Cygwin shell and change directory to root with 'cd /'.
2.3. Uncompress to Cygwin root with command:
'tar -jxvf cygwin-gcc-linux.tar.bz2'.

Cross-compilers are installed under '/opt/crosstool'. You can use them directly or with commands: gcc-linux, g++-linux, gcc-linux-2.95, g++-linux-2.95, gcc-linux-x86_64 and g++-linux-x86_64.

source : http://metamod-p.sourceforge.net/cross-compiling.on.windows.for.linux.html

'Domain > Win32' 카테고리의 다른 글

[Win32][Tips] Creating Window...  (0) 2007.06.27
[Win32] IME Active중 VK Code얻기  (0) 2007.06.25
[Win32] 한글 입력하기  (0) 2007.06.23
[Tips] cygwin 'make' issue  (0) 2007.06.13
[VC][Tips] 2005 express  (0) 2006.04.12
[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

* XP의 한계

저자가 이야기한 바와 같이 XP는 대규모 Project (여기서 말하는 대규모란, project를 하기 위해 필요한 사람 숫자가 많은 Project를 의미하는 것처럼 보인다 - 사람 숫자가 많다 = 필요한 Communication 양이 많다.)에는 적합하지 않은 것 같다. 이 점을 명확히 하고 XP를 적용하자.

* Test Oriented Development의 장점.
일단 Test Oriented로 하게 되면, Test를 위한 Interface를 가장 먼저 생각하게 된다. 즉 자연스럽게 "Interface Oriented Development"를 하게 된다. 또한 개발된 Program을 검증하기 용이할 확률이 높다. 중요한 것은 Auto Test란 것 자체가 논리적인 오류를 잡아낼 수는 있어도, User experience쪽에 부적합한 내용같은 부분은 잡아내는 것이 사실상 불가능 하다는 점이다. 또한 논리적인 오류 역시, 어느 정도 큰 Module을 대상으로 Auto Test를 돌리게 되면, 모든 경우를 Test하는 것이 상당히 어렵게 된다. 따라서 Auto Test는 작은 Unit Test에 적합한 것으로 보인다. (이렇게 하면, Test종류는 늘어나겠지만... )

* 고객의 역할.
고객은 business의 가치를 높이는 것이 무엇인지 파악하고, 무엇을 먼저 하고 무엇을 나중에 할 것인지를 결정하고, 시스템이 제대로 작동하는지 확인할 수 있는 test를 정의한다.

* 관리자의 역할.
관리자는 고객과 개발자를 한데 모으고 서로 융화시켜, 팀이 순조롭게 운영되도록 도와준다. 관리자는 process를 수행하는 것이 아니라, 단지 process가 원활하게 진행되도록 하는 것이다.
-> 훌륭한 관리자의 일은 처음부터 끝까지, 작업을 하고 있는 사람들 앞에 놓인 장애물을 치우는 일이다.

* XP 프로그램 작성.
- 코드의 공동 소유 : 누구든 현재 Project의 코드를 원하는 대로 수정할 수 있다.
- 단순한 설계 : 모든 test를 실행하고, 모든 idea를 표현하며, 최소한의 Class와 Method를 가지지만, 중복된 code를 포함하지 않는다.
- 지속적인 Refactoring: 기존 코드를 바꾸지 않는 이유는 잘못되는 것을 두려워해서이다. 따라서, 거의 100%가동되는 모든 단위 Test를 가지고 있다면 Refactoring은 두려워할 만한 일이 아니다.
- 지속적인 통합 : 지속적인 통합은 항상 releasable한 상태로 유지하고, 통합시에 나타날 수 있는 문제를 최대한 빨리 찾아낼 수 있다는 측면에서 중요하다. 통합이 늦어지면, debugging시 드는 비용은 늦어진 시간만큼 증가한다. 기하급수적으로...
- 코드작성표준
- 주당40시간 : 한 주 이상의 과도한 시간외 근무는, 코드의 질을 떨어뜨리며, bug를 양산하는 주범이다.

* 짝 Programming.
두 사람이 하나의 컴퓨터 앞에서 같이 Programming을 한다. "역동적인 2인조는 개별 Play를 하는 3명보다 낫다"
(=> 일단 XP에서는 이렇게 이야기하고 있는데... 난 여기에는 아직까진 동의할 수 없다. 이건 분명히 case by case..이다.!)
코드 공동 소유 vs. 코드의 건전성 유지.

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

XP(Extream programming)에 따르면, code branch는 항상 release가능한 상태를 유지해야 한다. 그런데 이는 XP에서 마찬가지로 주장하고 있는, "누구나 수정할 수 있고, 누구나 test가능한 code"의 개념과는 상반된다. 누구나 수정할 수 있고, 누구나 test가능하다면, 그 code branch는 언제든 깨어질 수 있다. 따라서, 항상 releasable할 수는 없다.

"누구나 수정할 수 있고, 누구나 test할 수 있다"는 것과 "코드는 항상 release가능한 상태를 유지해야 한다." 는 것을 어떻게 같이 가져갈 것인가????
나의 XP에 대한 지식이 짧아서 그런것 같은데...
(XP에서 어떻게 표현했는지, 그 정확한 영어 표현이 생각나지 않아서 한글로 적는다...)

+ Recent posts