작업표시줄의 “시작” 버튼 위치 이동시키기

옛날 델파이(Delphi) 할적에 Window 컨트롤에 대해 이런 저런 장난을 많이도 쳤었는데, VC++로 전향한 이후에는 그런 장난을 하지 못했습니다. 오늘 한번 VC++를 가지고 컨트롤 장난질을 해봅니다. 이미 식상한 내용이긴 합니다만…. 모처럼 코딩(한달넘게 못해뜸)을 하면서 머리에 기름칠(ㅡㅡ;)도 좀 할겸해서… ㅋ

전역 변수입니다. (굳이 전역을 빼지 않아두 될 것도 있습니만..)

HWND starthandle;
CWnd StartButton;
CRect rect;
int nWidth, nHeight;

“시작” 버튼을 이동시키는 코드입니다. 버튼 컨트롤에 대한 클릭 이벤트에 넣으면 적당하겠군요.

starthandle = ::FindWindowEx(0, 0, "Shell_TrayWnd", NULL);
starthandle = ::FindWindowEx(starthandle, 0, "Button", NULL);

StartButton.m_hWnd=starthandle;
StartButton.EnableWindow(TRUE);
StartButton.GetWindowRect(&rect);
nWidth = rect.Width();
nHeight = rect.Height();

StartButton.MoveWindow(nMove,0,nWidth, nHeight ,TRUE);
nMove+=10;

“시작” 버튼을 가지고 장난을 쳤으면 이제 다시 원상복귀를 시켜놔야겠죠? 🙂

starthandle = ::FindWindowEx(0, 0, "Shell_TrayWnd", NULL);
starthandle = ::FindWindowEx(starthandle, 0, "Button", NULL);
StartButton.m_hWnd=starthandle;
StartButton.MoveWindow(0,0,nWidth,nHeight,TRUE);

음.. 별 쓰잘때기 없는 거죠? ㅋ 하지만 위의 내용에 제법 요긴한게 있긴 합니다. 윈도우 클래스를 이용해서 윈도우 핸들 구하는 방법도 나와 있구요.. 윈도우 핸들가지고 객체화(OOP –;)해서 나중에 요긴하게 두루 두루 써먹는 기법도 나와있네요..

개인적으로는 이제 제발 좀 코딩을 즐겁게 해보자는 취지에서리…. 올려봅니다.

소켓을 우아하게 종료하기

서버나 클라이언트를 종료하고 netstat로 종료시에 소켓이 어떤 상태인지 살펴보면 ‘TIME_WAIT’으로 표시되어있는것을 볼수있습니다. 그리고 그것들은 잠시(몇분)후에 사라졌습니다. 소켓을 종료할때 이러한 ‘TIME_WAIT’ 과정을 거치지 않고 우아하게 바로 종료하는 방법은 아래와 같습니다.

code = ::shutdown( m_hSocket, SD_BOTH ); // Send a FIN here 

// Wait for socket to fail (ie closed by other end) 
if( code != SOCKET_ERROR ) 
{   
    fd_set readfds; 
    fd_set errorfds; 
    timeval timeout; 
    FD_ZERO( &readfds ); 
    FD_ZERO( &errorfds ); 
    FD_SET( m_hSocket, &readfds ); 
    FD_SET( m_hSocket, &errorfds ); 

    timeout.tv_sec  = MAX_LINGER_SECONDS; 
    timeout.tv_usec = 0; 
    ::select( 1, &readfds, NULL, &errorfds, &timeout ); 
} 

code = ::closesocket( m_hSocket ); 
m_hSocket = INVALID_SOCKET; 

이것이 ACK과 FIN을 기다는 방법입니다. 이렇게 하지 않았을때는 소켓은 오랜시간동안 TIME_WAIT의 대기과정을 거쳐야합니다.

[출처] 델마당(www.delmadang.com) 정승유님의 글