for /F "tokens=*" %1 in ('wevtutil.exe el') DO wevtutil.exe cl "%1"


wchar_t host[128];

memset(host,0,sizeof(host));

unsigned long dwHostLen = _countof(host);


struct sockaddr_storage addr;

int addr_len = sizeof(addr);


//if(getsockname(s, (struct sockaddr*)&addr, &addr_len) == SOCKET_ERROR) // 내 아이피/포트

if(getpeername(s, (struct sockaddr*)&addr, &addr_len) == SOCKET_ERROR) // 상대방 아이피/포트

{

MyTraceW(L"getsockname error %ld", WSAGetLastError());

}

else

{

WSAAddressToStringW((LPSOCKADDR)&addr, addr_len, NULL, host, &dwHostLen);

MyTraceW(L"send called s[%d] %X %ld bytes. to %s", (unsigned int)s, buf, len, host);

}


어떨때 쓰냐면 send 훅 한담에 소캣별로 패킷을 구분하고 싶을때


  1. Start the guest PC, and then defragment the guest PC hard disk.
  2. Obtain and then install a third-party data removal utility on the guest PC operating system.
  3. Run the third-party utility in the guest PC, and then configure it to zero out unused disk space. Use sdelete
  4. When this operation is complete, shut down the guest PC. 

    If you use "undoable" virtual hard disk images, commit the changes to the virtual hard disks.
  5. In Virtual PC, click Virtual Disk Wizard on the File menu.
  6. Click Next, click Examine or modify existing disk image, and then click Next.
  7. Click Browse, locate and then click the virtual hard disk image that you want to compact, click Open, and then click Next.
  8. Click Compact the disk image, and then click Next.
  9. Use one of the following methods to create a compacted disk image:
    • Click Use original file

      When you use this method, the virtual hard disk image is compacted to the same file as the original virtual hard disk image. This method uses less disk space on the host computer. However, if the virtual hard disk file becomes corrupted during the compaction process, you may lose guest PC data.
    • Click Select new file, click Browse, type a new file name for this virtual hard disk image, and then click Save.

      When you use this method, a new image file is created for the compacted virtual hard disk image. Because the original file is not overwritten during the compaction process, Microsoft recommends that you use this method. When you use this method, you can verify the integrity of the guest PC virtual hard disk before you have to remove the original virtual hard disk image.
  10. Click Next, and then click Finish.

    The virtual hard disk is compacted.
  11. On the message that states that the hard disk was compacted successfully, click Close.

The third-party products that this article discusses are manufactured by companies that are independent of Microsoft. Microsoft makes no warranty, implied or otherwise, regarding the performance or reliability of these products.



VitualBox 에서 용량줄이기.


1~4번까지 그대로 수행

오라클설치폴더\VBoxManage modyfyhd Win.vdi --compact


끝!


[Type1]

typedef void (CClientSocket::*TSendPacket)(const CprintPacket&);

TSendPacket lpSendPacket = (TSendPacket)&CClientSocket::SendPacket;

PDWORD pSendPacket = (PDWORD)&lpSendPacket;

pSendPacket = (PDWORD)*pSendPacket;


[Type2]

template <class T1, class T2>

T1 union_cast(T2 v)

{

  static_assert(sizeof(T1) >= sizeof(T2), "Bad union_cast!");

  union UT {T1 t1; T2 t2;} u;

  u.t2 = v;

  return u.t1;

}

class MyClass

{

public:

  void foo(int);

};

 

auto p = union_cast<void *>(&MyClass::foo);


[Type3]

void *DisMember(size_t size, ...)

{

    if (size != sizeof(void *)) return NULL;

    va_list args;

    va_start(args, size);

    void *res = va_arg(args, void *);

    va_end(args);

    return res;

}

 

// snip

void Base::MyMethod() { /* ... */ }

// snip

 

void *anything = DisMember(sizeof(void (Base::*)()), &Base::MyMethod);




[Type4]

LPVOID pVoid;

       __asm

       {

              push eax

              mov eax, CPatternSearch::BytePatternSearch

              mov pVoid, eax

              pop eax

       }


HANDLE hConsoleW, hConsoleR;

enum Color { black = 0, blue, green, cyan, red, purple, yellow, grey, dgrey, lblue, lgreen, lcyan, lred, lpurple, lyellow, white};


AllocConsole();

SetConsoleTitle(_T("Some title"));

hConsoleW = GetStdHandle(STD_OUTPUT_HANDLE);

hConsoleR = GetStdHandle(STD_INPUT_HANDLE);


void ConsoleOutput(TCHAR* lpszMessage, Color color = white){

int len = wcslen(lpszMessage);

DWORD numOfCharWritten;

SetConsoleTextAttribute(hConsoleW, color);

WriteConsole(hConsoleW, lpszMessage, len, &numOfCharWritten, NULL);

}



site:combatarms.nexon.net inurl:test

  1. 프로그램의 초기화시에 DragAcceptFiles(hWnd, TRUE) 함수를 호출한다. 첫 번째 인자인 hWnd는 드롭의 타겟이 되는 윈도우의 핸들이다.
    혹은 다이얼로그(윈도우)의 리소스에서 Accept Files 을 true로 둔다.
  2. 탐색기로부터 파일이 드롭되는 순간에 WM_DROPFILES 메시지가 날라온다. 이를 처리한다.
    혹은 해당 다이얼로드(윈도우)의 클래스에서 WM_DROPFILES 를 재정의한다. 

    	case WM_DROPFILES :
    	{
    		POINT pt;
    		// 어느 위치에 드롭되었는지 그 항목을 알아낸다.
    		if (DragQueryPoint((HDROP)wParam, &pt)) 
    		{
    			UINT i = 0;
    			// 모두 몇 개의 파일이 드롭되었는지 알아낸다.
    			// 만일 폴더가 드롭되었다면 폴더의 이름만 넘어온다.
    			UINT uCount = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL ,0);
    
    			for(i = 0;i < uCount;i++)
    			{
    				// 드롭된 파일의 이름을 알아온다.
    				DragQueryFile((HDROP)wParam, i, buffer ,255);
    				// 드롭된 파일 이름을 출력해본다.
    				MessageBox(hWnd, buffer, "File Name", MB_OK);
    			}
    		}
    		// drag and drop 작업을 끝낸다.
    		DragFinish((HDROP)wParam);
    		break;
    	}
    
  3. Drag&drop을 더 사용할 필요가 없어지면 DragAcceptFiles를 호출한다.
    	DragAcceptFiles(hWnd, FALSE);




services.msc -> Shell Hardware Detection -> 사용안함

gpedit.msc -> Computer Configuration -> Administrative Template -> Windows Components -> AutoPlay Policies -> Turn Off Autoplay 실행 -> Enable 설정 -> 모든드라이브

하나의 솔루션에 여러개의 프로젝트로 작업을 할 때가 있습니다. 

독입된 프로젝트로 동작한다면 디버깅에 문제는 없지만 만일 서버-클라이언트 구조라면 어떻게 해야할까요? 


VC 를 서버용, 클라용 두개를 띄워서 작업한다?

그렇게만 되면 오히려 더 깔끔할것 같긴합니다. (이건 혹시나 방법이 있을지도 모르겠네요)

PC를 2대로 테스트한다? 이건 더 좋은 방법이겠죠. (소스 통합은 형상관리툴로 하고..)


하지만 그런 상황이 안된다면 아래와 같은 방법으로 하나의 VS로 모두 디버깅을 할 수 있습니다. 


솔루션 -> 속성 -> 시작 프로젝트 -> Multiple startup project 선택



동시에 실행시킬 프로젝트에 대해서 Action 의 값을 Start 로 변경시켜줍니다.


만일 프로젝트의 실행 순서가 있다면 오른쪽 화살표로 순서를 변경시켜줍니다. 


저같은 경우 서버를 먼저 실행시키고, 클라이언트를 나중에 실행시키도록 설정하였습니다. 


그럼 이만~!






* 삭제된 헤더파일이 프로젝트에 포함되어 있는 경우

* Debug 폴더를 날린다.

* Clean 을 한다..


등등 어떤짓을 하면 해결된다는데 난 안되는군.


일단 리서치중.

약 한시간 가량 빡치게 만든에러..


MS 는 CreateProcess 의 버그를 고칠 생각이 없는가? 구조적으로 힘든가? 아무튼 이런 빡치는 상황이 발생하면 아래와 같이 수정하세요.


먼저 CreateProcess 를 사용하는 수천만명이 봤을 간단한 예제를 봅시다. 

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682512(v=vs.85).aspx


빨간 부분을 수정했습니다. 


#include <windows.h> #include <stdio.h> #include <tchar.h> void _tmain( int argc, TCHAR *argv[] ) { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); if( argc != 2 ) { printf("Usage: %s [cmdline]\n", argv[0]); return; } // Start the child process. if( !CreateProcess( NULL, // No module name (use command line) _T("notepad.exe"), // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { printf( "CreateProcess failed (%d).\n", GetLastError() ); return; } // Wait until child process exits. WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); }


이렇게 한 뒤에 unicode 로 빌드하면 빡치는 상황이 발생합니다. 바로 Access violation error!!!!!!!!!!!!


그 원인은 unicode 버전의 createprocess 는 lpCommandLine 파라미터를 변경시키기 때문에 const 메모리 주소를 전달하면 안됩니다. 

아래 msdn 에 설명되어 있습니다. 


lpCommandLine [in, out, optional]

The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null character. If lpApplicationName is NULL, the module name portion of lpCommandLine is limited to MAX_PATH characters.

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to bylpApplicationName as the command line.

If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string pointed to bylpApplicationName specifies the module to execute, and the null-terminated string pointed to by lpCommandLinespecifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first token in the command line.

int get_computer_name(BYTE *computer_name, DWORD *computer_name_lg)

{

   HKEY hKey;

   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,

               "SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName",

               0, KEY_QUERY_VALUE, &hKey ) != ERROR_SUCCESS)

      return FALSE;

   if (RegQueryValueEx(hKey, "ComputerName", NULL, NULL,

                       (LPBYTE) computer_name,

                       (LPDWORD) computer_name_lg) != ERROR_SUCCESS) {

      RegCloseKey(hKey);

      return FALSE;

   }

   RegCloseKey(hKey);

   return TRUE;

}


테스트는 안해봄. 

UINT64 get_cpuid(void)

{

   DWORD dwStandard = 0; 

   DWORD dwFeature = 0; 

     

   _asm { 

        mov eax, 1 

        cpuid 

        mov dwStandard, eax 

        mov dwFeature, edx 

    }

    return( ((UINT64)(dwFeature) << 32) | ((UINT64)(dwStandard)));

}


int _tmain(int argc, _TCHAR* argv[])

{

UINT64 cpuid;

cpuid = get_cpuid();

printf("CPU ID : %.I64X\n", cpuid);

return 0;

}


이 프로그램이 다른 PC에서도 먹힐까? 테스트를 해봐야 할듯.. 


ps. 같은 브랜드의 PC에서 테스트해본결과 값이 동일하다... 망 글..

CONVERT(INET_NTOA(ip) USING latin1) as s_ip, : ip 값은 dword 이며 Bigendian 으로 저장된 IP 정보이다. 이걸 문자열로 이쁘게 표시하기 위하여 컨버팅을 한다. 


HEX(ver) as ver : ver는 dword 값이다. 이걸 hex string 으로 컨버팅해서 표시한다.


DATE_SUB(CURDATE(), INTERVAL 1 DAY) : 현재 일자로부터 1일을 뺀 날짜를 반환한다.


DATE_FORMAT(logdate, '%Y-%m-%d') : DATE 타입의 logdate 컬럼을 YYYY-MM-DD 형태로 컨버팅한다.


timediff(logdate,pct) as time_diff : DATE 타입의 logdate 컬럼과 DATE 타입의 pct 컬럼 값 뺀 DATE 타입 값을 반환한다.


insert into aaa values(1) where not exists(select ip from ip_table where ip=1); : ip_table 에 ip 컬럼값이 1인 row 가 없으면 입력한다.


SUBSTRING(dat, 2, 4) : dat 문자열의 2번째 문자부터 4번째문자까지 반환한다.

간혹다가 이런 에러에 직면할때가 있습니다. 


[원인]

"AppNameDlg.h" 에서 resource.h 에 선언해둔 IDD_#### 을 참조하지 못하여 발생함. 

"AppNameDlg.cpp" 에서는 "AppName.h" 와 "AppNameDlg.h" 를 include 합니다. 

이때 "AppName.h" 내부에서 "resource.h" 를 include 하기 때문에 순서상으로 오류가 발생하지 않아야 합니다. 

하지만 간혹 "AppNameDlg" 클래스를 참조하기 위하여 다른 cpp 파일에서 "AppNameDlg.h" 를 include 를 할때가 있는데 이런 경우 위와 같은 오류가 발생합니다.  


[해결방안]

* 다른 cpp 파일에서 #include "AppNameDlg.h" 위에 #include "AppName.h" 를 추가한다. (전체적인 구조대로 구현)

* "AppNameDlg.h" 에서 #include "resource.h" 를 추가한다. 


끝!

drop user 'username'@'host_ip_addr';


GRANT select on dbname.tablename to 'username'@'host_ip_addr' IDENTIFIED BY 'password';


show grants for username@'host_ip_addr';



 http://codenongsa.egloos.com/258234 

이걸 참고하자. 

#include<windows.h>
#include<wininet.h>
#include<iostream.h>

void main(int argc, char *argv[])
{
    if (argc != 3)
    {
        cout << "Usage: progress <host> <object>" << endl;
        return;
    }

    HINTERNET hSession = InternetOpen("WinInet Progress Sample",
                                      INTERNET_OPEN_TYPE_PRECONFIG,
                                      NULL,
                                      NULL,
                                      0);
    HINTERNET hConnection = InternetConnect(hSession,
                                            argv[1],  // Server
                                            INTERNET_DEFAULT_HTTP_PORT,
                                            NULL,     // Username
                                            NULL,     // Password
                                            INTERNET_SERVICE_HTTP,
                                            0,        // Synchronous
                                            NULL);    // No Context

    HINTERNET hRequest = HttpOpenRequest(hConnection,
                                         "GET",
                                         argv[2],
                                         NULL,    // Default HTTP Version
                                         NULL,    // No Referer
                                         (const char**)"*/*\0", // Accept
                                                                // anything
                                         0,       // Flags
                                         NULL);   // No Context
    HttpSendRequest(hRequest,
                    NULL,    // No extra headers
                    0,       // Header length
                    NULL,    // No Body
                    0);      // Body length

    DWORD dwContentLen;
    DWORD dwBufLen = sizeof(dwContentLen);
    if (HttpQueryInfo(hRequest,
                      HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
                      (LPVOID)&dwContentLen,
                      &dwBufLen,
                      0))
    {
        // You have a content length so you can calculate percent complete
        char *pData = (char*)GlobalAlloc(GMEM_FIXED, dwContentLen + 1);
        DWORD dwReadSize = dwContentLen / 10;   // We will read 10% of data
                                                // with each read.

        cout << "Download Progress:" << endl;
        cout << "    0----------100%" << endl;
        cout << "     ";
        cout.flush();

        DWORD cReadCount;
        DWORD dwBytesRead;
        char *pCopyPtr = pData;
        for (cReadCount = 0; cReadCount < 10; cReadCount++)
        {
            InternetReadFile(hRequest, pCopyPtr, dwReadSize, &dwBytesRead);
            cout << "*";
            cout.flush();
            pCopyPtr = pCopyPtr + dwBytesRead;
        }
        // extra read to account for integer division round off
        InternetReadFile(hRequest,
                         pCopyPtr,
                         dwContentLen - (pCopyPtr - pData),
                         &dwBytesRead);
        // Null terminate data
        pData[dwContentLen] = 0;

        // Display
        cout << endl << "Download Complete" << endl;
        cout << pData;
    }
    else
    {
        DWORD err = GetLastError();
        // No content length...impossible to calculate % complete
        // Just read until we are done.
        char pData[100];
        DWORD dwBytesRead = 1;
        while (dwBytesRead)
        {
            InternetReadFile(hRequest, pData, 99, &dwBytesRead);
            pData[dwBytesRead] = 0;
            cout << pData;
        }
    }
}

defaults write -globalDomain com.apple.mouse.scaling -float 4.0 콘솔 띄워서 위 명령어를 입력한다. 마지막 수치가 높을 경우 속도가 빨라진다.
출처 : http://www.searchlores.org/protec/inbarraz.txt


                            Anti Debugging Tricks

                                     By:

                                  Inbar Raz

                 Assistance by Eden Shochat and Yossi Gottlieb

                               Release number 5

  Today's anti debugging tricks devide into two categories:

  1. Preventive actions;
  2. Self-modifying code.

  Most debugging tricks, as for today, are used within viruses, in order to
avoid dis-assembly of the virus, as it will be exampled later in this file.
Another large portion of anti debugging tricks is found with software
protection programs, that use them in order to make the cracking of the
protection harder.

1. Preventive actions:
----------------------

  Preventive actions are, basically, actions that the program takes in order
to make the user unable to dis-assemble the code or trace it while running.

1.1. Interrupt disable:

       Interrupt disable is probably the most common form of anti-debugging
     tricks. It can be done in several ways:

   1.1.1. Hardware masking of interrupt:

            In order to avoid tracing of a code, one usually disables the
          interrupt via the 8259 Interrupt Controller, addressed by read/write
          actions to port 21h. The 8259 Interrupt Controller controls the IRQ
          lines. This means that any IRQ between 0 and 7 may be disabled by
          this action. Bit 0 is IRQ0, bit 1 is IRQ1 etc. Since IRQ1 is the
          keyboard interrupt, you may disable the keyboard without the
          debugger being able to bypass it.

          Example:

          CS:0100 E421           IN     AL,21
          CS:0102 0C02           OR     AL,02
          CS:0104 E621           OUT    21,AL

            Just as a side notice, the keyboard may be also disabled by
          commanding the Programmable Peripheral Interface (PPI), port 61h.

          Example:

          CS:0100 E461           IN     AL,61
          CS:0102 0C80           OR     AL,80
          CS:0104 E661           OUT    61,AL

   1.1.2. Software masking of interrupt:

            This is quite an easy form of an anti-debugging trick. All you
          have to do is simply replace the vectors of interrupts debuggers
          use, or any other interrupt you will not be using or expecting to
          occur. Do not forget to restore the original vectors when you are
          finished. It is adviseable to use manual change of vector, as shown
          below, rather than to change it using interrupt 21h service 25h,
          because any debugger that has gained control of interrupt 21h may
          replace your vector with the debugger's. The example shows an
          interception of interrupt 03h - the breakpoint interrupt.

          Example:

          CS:0100 EB04           JMP    0106
          CS:0102 0000           ADD    [BX+SI],AL
          CS:0104 0000           ADD    [BX+SI],AL
          CS:0106 31C0           XOR    AX,AX
          CS:0108 8EC0           MOV    ES,AX
          CS:010A 268B1E0C00     MOV    BX,ES:[000C]
          CS:010F 891E0201       MOV    [0102],BX
          CS:0113 268B1E0E00     MOV    BX,ES:[000E]
          CS:0118 891E0401       MOV    [0104],BX
          CS:011C 26C7064C000000 MOV    Word Ptr ES:[000C],0000
          CS:0123 26C7064E000000 MOV    Word Ptr ES:[000E],0000

   1.1.3. Vector manipulation

             This method involves manipulations of the interrupt vectors,
          mainly for proper activation of the algorithm. Such action, as
          exampled, may be used to decrypt a code (see also 2.1), using data
          stored ON the vectors. Ofcourse, during normal operation of the
          program, vectors 01h and 03h are not used, so unless you are trying
          to debug such a program, it works fine.

          Example:

          CS:0100 31C0           XOR    AX,AX
          CS:0102 8ED0           MOV    SS,AX
          CS:0104 BC0E00         MOV    SP,000E
          CS:0107 2E8B0E3412     MOV    CX,CS:[1234]
          CS:010C 50             PUSH   AX
          CS:010D 31C8           XOR    AX,CX
          CS:010F 21C5           AND    BP,AX
          CS:0111 58             POP    AX
          CS:0112 E2F8           LOOP   010C

   1.1.4. Interrupt replacement

            This is a really nasty trick, and it should be used ONLY if you
          are ABSOLUTELY sure that your programs needs no more debugging. What
          you should do is copy the vectors of some interrupts you will be
          using, say 16h and 21h, onto the vectors of interrupt 01h and 03h,
          that do not occur during normal operation of the program. If the
          user wants to debug the program, he would have to search for every
          occurance of INT 01, and replace it with the appropriate INT
          instruction. This trick is very effective if used together with the
          fact that the INT 3 intruction has a ONE BYTE opcode - 0CCh, which
          can not be changed to any other interrupt.

          Example:

          CS:0100 FA             CLI
          CS:0101 31C0           XOR    AX,AX
          CS:0103 8EC0           MOV    ES,AX
          CS:0105 26A18400       MOV    AX,ES:[0084]
          CS:0109 26A30400       MOV    ES:[0004],AX
          CS:010D 26A18600       MOV    AX,ES:[0086]
          CS:0111 26A30600       MOV    ES:[0006],AX
          CS:0115 B44C           MOV    AH,4C
          CS:0117 CD01           INT    01               

1.2. Time watch:

       This may be a less common method, but it is usefull against debuggers
     that disable all interrupts except for the time that the program is
     executed, such as Borland's Turbo Debugger. This method simply retains
     the value of the clock counter, updated by interrupt 08h, and waits in an
     infinite loop until the value changes. Another example is when you mask
     the timer interrupt by ORing the value INed from port 21h with 01h and
     then OUTing it back, thus disabling the IRQ0 - Timer interrupt. Note that
     this method is usefull only against RUN actions, not TRACE/PROCEED ones.

     Example:

     CS:0100 2BC0           SUB    AX,AX
     CS:0102 FB             STI
     CS:0103 8ED8           MOV    DS,AX
     CS:0105 8A266C04       MOV    AH,[046C]
     CS:0109 A06C04         MOV    AL,[046C]
     CS:010C 3AC4           CMP    AL,AH
     CS:010E 74F9           JZ     0109

1.3. Fool the debugger:

       This is a very nice technique, that works especially and only on those
     who use Turbo Debugger or its kind. What you should do is init a jump to
     a middle of an instruction, whereas the real address actually contains
     another opcode. If you work with a normal step debugger such as Debug or
     SymDeb, it won't work since the debugger jumps to the exact address of
     the jump, and not to the beginning of an instruction at the closest
     address, like Turbo Debugger.

     Example:

     CS:0100 E421           IN     AL,21
     CS:0102 B0FF           MOV    AL,FF
     CS:0104 EB02           JMP    0108
     CS:0106 C606E62100     MOV    Byte Ptr [21E6],00
     CS:010B CD20           INT    20

     Watch this:

     CS:0108 E621           OUT    21,AL

     Notice:

       This trick does NOT effect the run of the program in ANY debugger. Its
     only use is to try to deceive the user into thinking another opcode is
     used, while another is actually run.

1.4. Check CPU Flags:

       This is a nice trick, effective against almost any real mode debugger.
     What you should do is simply set the trace flag off somewhere in your
     program, and check for it later. If it was turned on, a debugger runs in
     the background...

     Example:

     CS:0100 9C             PUSHF
     CS:0101 58             POP    AX
     CS:0102 25FFFE         AND    AX,FEFF
     CS:0105 50             PUSH   AX
     CS:0106 9D             POPF

     In the middle of the program:

     CS:1523 9C             PUSHF
     CS:1524 58             POP    AX
     CS:1525 250001         AND    AX,0100
     CS:1528 7402           JZ     152C
     CS:152A CD20           INT    20

1.5. Cause debugger to stop execution:

       This is a technique that causes a debugger to stop the execution of a
     certain program. What you need to do is to put some INT 3 instructions
     over the code, at random places, and any debugger trying to run will stop
     there. It is best if used within a loop, as it is run several times.

     Example:

     CS:0100 B96402         MOV    CX,0264
     CS:0103 BE1001         MOV    SI,0110
     CS:0106 AC             LODSB
     CS:0107 CC             INT    3
     CS:0108 98             CBW
     CS:0109 01C3           ADD    BX,AX
     CS:010B E2F9           LOOP   0106

1.6. Halt computer using stack:

       This trick is based on the fact that debuggers don't usually use a
     stack space of their own, but rather the user program's stack space. By
     setting the stack to a location in the middle of a code that does NOT use
     the stack itself, any debugger that will try to trace the code will
     overwrite some of the code by its own stack (mainly interrupt return
     addresses). Again, CLI and STI are in order, and are not shown for the
     purpose of the example only. They must be included, or you risk hanging
     your computer wether a debugger is installed or not.

     Example:

     CS:0100 8CD0           MOV    AX,SS
     CS:0102 89E3           MOV    BX,SP
     CS:0104 0E             PUSH   CS
     CS:0105 17             POP    SS
     CS:0106 BC0B01         MOV    SP,010B
     CS:0109 90             NOP
     CS:010A 90             NOP
     CS:010B EB02           JMP    010F
     CS:010D 90             NOP
     CS:010E 90             NOP
     CS:010F 89DC           MOV    SP,BX
     CS:0111 8ED0           MOV    SS,AX

1.7. Halt TD386 V8086 mode:

       This is a nice way to fool Turbo Debugger's V8086 module (TD386). It is
     based on the fact that TD386 does not use INT 00h to detect division by
     zero (or register overrun after division, which is treated by the
     processor in the same way as in the case of division by zero). When TD386
     detects a division fault, it aborts, reporting about the faulty division.
     In real mode (even under a regular debugger), a faulty DIV instruction
     will cause INT 00h to be called. Therefore, pointing INT 00h to the next
     instruction, will recover from the faulty DIV.

     Note: It is very important to restore INT 00h's vector. Otherwise, the
     next call to INT 00h will cause the machine to hang.

     Example:

     CS:0100 31C0          XOR     AX,AX
     CS:0102 8ED8          MOV     DS,AX
     CS:0104 C70600001201  MOV     WORD PTR [0000],0112
     CS:010A 8C0E0200      MOV     [0002],CS
     CS:010E B400          MOV     AH,00
     CS:0110 F6F4          DIV     AH
     CS:0112 B8004C        MOV     AX,4C00
     CS:0115 CD21          INT     21

1.8. Halt any V8086 process:

       Another way of messing TD386 is fooling it into an exception.
     Unfortunately, this exception will also be generated under any other
     program, running at V8086 mode. The exception is exception #13, and its
     issued interrupt is INT 0Dh - 13d. The idea is very similar to the
     divide by zero trick: Causing an exception, when the exception interrupt
     points to somewhere in the program's code. It will always work when the
     machine is running in real mode, but never under the V8086 mode.

     Note: It is very important to restore the original interrupt vectors.
     Otherwise, the next exception will hang the machine.

     Example:

     CS:0100 31C0          XOR     AX,AX
     CS:0102 8ED8          MOV     DS,AX
     CS:0104 C70634001301  MOV     WORD PTR [0034],0113
     CS:010A 8C0E3600      MOV     [0036],CS
     CS:010E 833EFFFF00    CMP     WORD PTR [FFFF],+00
     CS:0113 B8004C        MOV     AX,4C00
     CS:0116 CD21          INT     21

2. Self-modifying code:
-----------------------

2.1. Encryptive/decryptive algorithm:

       The first category is simply a code, that has been encrypted, and has
     been added a decryption routine. The trick here is that when a debugger
     sets up a breakpoint, it simply places the opcode CCh (INT 03h) in the
     desired address, and once that interrupt is executed, the debugger
     regains control of things. If you try to set a breakpoint AFTER the
     decryption algorithm, what is usually needed, you will end up putting an
     opcode CCh in a place where decryptive actions are taken, therefore losing
     your original CCh in favour of whatever the decryption algorithm produces.
     The following example was extracted from the Haifa virus. If you try to
     set a breakpoint at address CS:0110, you will never reach that address,
     since there is no way to know what will result from the change. Note that
     if you want to make the tracing even harder, you should start the
     decryption of the code from its END, so it takes the whole operation
     until the opcode following the decryption routine is decrypted.

     Example:

     CS:0100 BB7109         MOV    BX,0971
     CS:0103 BE1001         MOV    DI,0110
     CS:0106 91             XCHG   AX,CX
     CS:0107 91             XCHG   AX,CX
     CS:0108 2E803597       XOR    Byte Ptr CS:[DI],97
     CS:010C 47             INC    DI
     CS:010D 4B             DEC    BX
     CS:010E 75F6           JNZ    0106
     CS:0110 07             POP    ES
     CS:0111 07             POP    ES

2.2. Self-modifying code:

   2.2.1. Simple self-modification:

            This method implements the same principle as the encryption
          method: Change the opcode before using it. In the following example,
          we change the insruction following the call, and therefore, if you
          try to trace the entire call ('P'/Debug or F8/Turbo Debugger), you
          will not succeed, since the debugger will put its CCh on offset 103h,
          but when the routine runs, it overwrites location 103h.

          Example:

          CS:0100 E80400         CALL   0107
          CS:0103 CD20           INT    20
          CS:0105 CD21           INT    21
          CS:0107 C7060301B44C   MOV    Word Ptr [0103],4CB4
          CS:010D C3             RET

          Watch this:

          CS:0103 B44C           MOV    AH,4C

   2.2.2. The Running Line (self-decrypting):

            This is an example of a self-tracing self-modifying code,
          sometimes called 'The running line'. It was presented by Serge
          Pachkovsky. It is a bit tricky in implementation, but, unlike
          all other techiniques mentioned in this document, it is relatively
          resistive to various protections of the vector table. In short, it
          results in instructions being decoded one at time, thus never
          exposing long code fragments to analisys. I will illustrate it
          with the following (over-simplified) code example:

          XOR     AX, AX
          MOV     ES, AX
          MOV     WORD PTR ES:[4*1+0],OFFSET TRACER
          MOV     WORD PTR ES:[4*1+2],CS
          MOV     BP, SP
          PUSHF
          XOR     BYTE PTR [BP-1], 1
          POPF
          MOV     AX, 4C00H               ; This will not be traced!
          DB      3 DUP ( 98H )
          DB      C5H, 21H

   TRACER:

          PUSH    BP
          MOV     BP, SP
          MOV     BP, WORD PTR [BP+2]
          XOR     BYTE PTR CS:[BP-1], 8
          XOR     BYTE PTR CS:[BP+0], 8
          POP     BP
          IRET

===============================================================================

Comments:

In order to save lines of code, I did not insert the CLI/STI pair before any
vector change. However, it is adviseable to do this pair before ANY manual
vector change, because if any interrupt occurs in the middle of your
operations, the machine could hang.

An apology:

In previous releases of this article, a false example, as noted by Serge
Pachkovksy, was posted. That was 2.2.2 - Manipulating the PIQ. Apperantly
the posted source would not work under any circumstances. In return, Serge has
presented the 'Running Line' technique.
네트워크 IP 를 변경한다던지 연결 상태를 확인한다던지 할때마다 

바탕화면 -> 내 네트워크환경 -> 마우스 우클릭 -> 속성 

혹은

제어판 ->  네트워크 연결

으로 찾아갔는데 종종 일부 몰지각한 PC방에서는 이 모든 시도를 원천봉쇄를 해놓았습니다.

그럼 명령어를 사용하는 수 밖에 없죠.

네트워크 환경 속성창 열기

시작 -> 실행
ncpa.cpl

boost 라이브러리를 빌드할때 저처럼 VC 2005 와 VC 2008 을 함께 설치되어 있는 상태에서 boost 를 빌드하면

VC 2008 용으로 라이브러리가 생성됩니다. 

그럼 VC 2005 에서는 라이브러리를 못찾으니 링크 에러가 뜨는데요.

VC 2005 용 라이브러리를 강제로 만들수 있습니다.

1. boost 를 다운받는다. (설치 방법은 버전에 따라 다소 다를 수 있음)
2. boost 압출을 풀어서 적당한 위치에 둔다.
3. 시작 -> 모든프로그램 -> visual studio command~~~ 실행
4. boost 폴더를 이동후 bootstrap.bat 실행
5. b2 실행. (이때 옵션에 따라 라이브러리 버전을 변경할 수 있음)
 b2 toolset=msvc-8.0 엔터
 b2 toolset=msvc-9.0 엔터
 b2 toolset=msvc-10.0 variant=debug,release link=static,shared threading=single,multi address-model=32 runtime-link=static,shared


bjam.exe toolset=msvc-8.0

toolset 옵션을 변경했을 때 아래와 같이 vc80 용 라이브러리와 vc90 용 라이브러리가 함께 위치합니다.

 


VC 으로 개발을 하다보면 종종 겪는 에러 입니다. 

저는 stdafx.cpp 를 프로젝트에서 뺏다가 다시 추가했더니 이런 에러가 뜨더군요. 

2>------ Build started: Project: XXXX, Configuration: Debug Win32 ------
2>Compiling...
2>XXXX.cpp
2>d:\XXXX\XXXX.cpp(4) : error C2859: d:\XXXX\debug\vc80.pdb is not the pdb file that was used when this precompiled header was created, recreate the precompiled header.
2>d:\XXXX\XXXX.cpp(4) : error C2859: d:\XXXX\debug\vc80.idb is not the idb file that was used when this precompiled header was created, recreate the precompiled header.
2>Build log was saved at "file://d:\XXXX\Debug\BuildLog.htm"
2>XXXX - 2 error(s), 0 warning(s) 

인터넷을 살펴보면 일반적으로

프로젝트 세팅 -> C/C++ 컴파일러 -> Precompiled Headers 에서

Create/Use Precompiled Header 항목을  Not Using Precompiled Headers 으로 해결하라고 합니다. 

하지만 이 방법은 큰 프로젝트에서는 빌드시간이 늘어나는 단점이 있습니다. 

위 설명대로 vc80.idb 를 새로 생성하면 됩니다. 

솔루션 탐색기에서 stdafx.cpp 의 Property Page 를 열어서 Precompiled Headers 의 

Create/Use Precompiled Header 항목을  Create Precompiled Header (/Yc) 으로 바꾼뒤에 빌드를 하면 새로 생성됩니다. 

일반적으로 Precompiled Header 옵션으로 프로젝트를 생성하면 다른 cpp 파일은 Use Precompiled Header (/Yu) 인데 stdafx.cpp 만 Create Precompiled Header (/Yc) 임을 알 수 있습니다. 

wish list

[케이스]
SNAP2-MR / MB - 스마트커버랑 호환불가.
iPad2 Weav Red / AVING - 가죽형태의 전체 커버. 다이어리같음. 스마트커버 호환불가
큐릭스 TPU Fitting Cover - 젤리느낌. 그닥
키스헤링 아이커버 - 비쌈 5만원. 보호필름 줌.
베루스 프리미엄 k 스마트 가죽케이스.- 고급스러운 가죽형태.심플함.

많이도 받았구나~

1945Plus
2011 Bubble Pops
30Days Kor.. 1.1
4music 1
7DA Zombie
a.xls
AccuSmart Camera 1.110
AcePoolHD 1.0
ADSudoku
AirComix
Alarm Clock
AlarmEngK12uskr 1
AllThatClassic
AmplioWords
AngelRush
aNote Lite 5.0
aRelax Ambi 1
Armory 3.0.0
Art Of War 2
Art Of War 2E
Assault Commando 1
AssistantForSC2_KR
ATC 교향곡
ATC 협주곡
Audio Jokes
Auditorium
Avatar Mobile
Babel Rising 1.3.1
BabylonTwins 1
Banzai Rabbit 1
BatteryLife 1.1.1
Battle Bears 1.6.1
BattleZone
Bdrive 1.0.2
beastfarmer 1.1
Big Fish 1.2.3
BigFish
BlastOff
Blimp 1.3
BlockExitFree
Bloody Rush
BMW M Meter
BookLayout 1.2
Bubble Smile 2.0.1
BubbleBubble2 1.2
Budgets! 2.7
Bug Heroes 2.0.1
Bump 2.4.2
Calculator 1.1.2
caligochaser
CalorieDowner
CamCard
Catacombs
CC Ninja 1.4
CC Tennis 1.4
CGV 2.0.1
ChekView
CityOfSecrets 1.1
ClassicVOY 1.1
ClownAround 1.1.1
CM
Coastal Def.
COD Zombies 1
CollectionISD 1.2
Color Fill
com.apple.iBooks.zip
Connect 1.0.2
Contacts AIO 2.0
Convert Units
CoolPuzzle 1.0 1
CoverMosaic 1
CrazyRemoteLite 2.2.3
Crimsonworld 1.0
Crimsonworld 1.1
CrystalWar0 2.0.2
CtC Free
CtC
Cut the Rope 2
Cut the Rope
Dark Nebula
DarkNebula2 1.1
DarkRaiderS 1.4
DarkShrine3D 1.07
Daum 2.6.3
Daum maps 2.0.4
DD Best1
DeadlyD
Deer Hunting 1
Dictionary 1
Dictionary!
Digits 2.0.1
DinkyBall
Diptic
Dirt Moto
Doodle Bomb
Doodle Food 1
Doodle Sky Pro
DoodleKart 1
Dr.Style
Dracula Pt1
DrivingCare 1.0.5
DungeonHunter 1
Earth Defend
Easyvoca4i-434 1
Easyvoca4i-913
EduBook 1
EggScramble
ElementZ 3.1
EliminatePro
EmojiArt 1.3
ePhotoChest 2.1
Errands
Evernote 3.3.10
EZ Sokoban
Facebook 3410
FaceFighter 1
FaceMan 2.6
Falling Fred 1.0.5
FF Lite 2.0
Files 1.8.3
FingerShooter 1.2
Fish Farm
FisherMan
Flood-It! 1
Flood-It! 2
FMX Riders 1.2
Forsaken 1.0
fring 5.0.0
Fun.Kor1
gas knight
Gasp 1.1
Geared 1.80
GlassTower2 1.7
Glow Stick Fr 1.3
GLWG 1.2
GodFinger
Goku Flight
GOM 1.4.0
GoodReader
Google 0.8.1
Google Earth 3.1.0
GraalClassic 1.9
Grand Tour 1.5.0
Graphicus 1.2.1
Gravity Sling 1.2
GravityWell 1.0
GreatTankWar 1
Grenade Box 1
GroundEffect
GroupSMS
Guitar Pro 1.0.6
Gun Bros.
GunsNGlory 1.3.21 1
GV Mobile + 2.2.0429
H.W. Mail
Hairstyles 1
HappyReading
Haypi Kingdom
Heavy Crossbow 2
HeavyGunner
HellKid Free 1.6.3
Highborn 1.2.1
HikeMateGPS 2.5.2
HootSuite 2.1.2
Hottest Apps
Hudriks 1.1
Hungry Shark Pt1 1
i-Gun 1.17
iAlbum
iBill 2.2
iBlast Moki
iBomber 1.4
iBooks 1.2.1
iChm Lite
iComic Viewer 2.1.1
iconlogic 2.3
iDaft 2.2
iDota
iFighter 2
iFighter
iFighterLite
iFreeSMSlite 1
iHandy Level 1
iHappyDays2 1
iJewels
iKana
iKorway
iMembership 2.3.0.0429
iNeedCoffee 2.0.2
iNetMania
Inkstrumental 1.2
iOrgel Pro 1
iPTT
iQuarium
iRemocon 1.2
iScience
iShaku LT
iShoot 2.12
iSlash 1.3.1
iSleep Sphere 1
iStarDict 1
iTistory 1
iWT 2.0
iZombieDM 1
J-Day War
Jihachul Pro
JIRA Mate
KakaoTalk 2.5.2
KartriderRush 1.0.0
King Strike 1
Konglish 1
Korea Times
KoreanDishes
koZipCode
LeadingWatch 2
LeadingWatch
Legend of Master
Legends 1.7
Lets Flair 1
LetsGolf
Libra Balance 1
LilRacerz 1.33
LiveSketch
Lo-Mob 1
Lost Cavern
Low Grav
m&Talk 1.091
Mango 2.3.1
me2day 1.8.0
Meditation 1
Meemo 1.6.1
METAL GEAR SOLID TOUCH Lite
Minigore 5.0
MiniSquadron
Monkey2_ Lite 1
MonsterKill 1
MonsterTN 1
Moodagent 2.2
MoreLomo 1
MoreNoel
MosaicArtist
MoSS
MotoChaser
Mr.Space!! 1
My Artists
My Brute 1
MyCard
MyContact
MyFamily
MyGroup 3.0.2
myMonolog 1.0.2
MyWonderfulDays 1.0
N.Y.Z.
nateon 1.1.1
Naver Map 2.6.4
Naver Webtoon
NaverClock
Net Status 1
Net Utility
Nimbuzz 1
NPCD Adv
N드라이브 1.3.6
Ocarina 1.4.3
OldPhotoPRO
olleh navi 1
OnlineNote
OPlayer Lite 1.27
Osfoora 1.7.2
Owl
P. Squadron
Pang
Paper Toss 1.81
Paris 1.2.4
pDownloader 1.7
PeekabooDD 2.10
Photo Mess 2.3.1
Photo Viewer Lite
PhotoFunia
PhotoPocket 1.7.5
Physics 1.9
PHYZIOS std
PICT.Edge 1
Ping
PirateNation 1
PlayMove 1.0
Ployd Black Box 1.1.0
Power Gems 1
Premium TWT 1.0.2
procreate 1.02
PS Express 1.5.3
PushPush2 1.0.7
PuzzleQuest
QRooQRoo 1.6.4.6
Quell
Racing
Ragdoll 2
RamyunTimerLite
ReaddleDocs 2.3.1
Retro Fighter 1
Ringtone Pro 1
Robin Hood
Roswell
Runner 1
Samurai
Sandstorm 1
Save Our Souls
Saving Private Sheep 1.3
SB 2.01
SC2
ScanSearch 1.3.2
SEED 2.0.3
SekaiCamera
Sentinel 1.8.2
Sentinel 2 1
Seoul Bus 2.2.2
SethGodin
SF 1.5
Shanghai Lite 1
SheepLauncherFree! 1
Sim_ SC2
SketchBookX 1.3.2
Skype 3.0.1
Slay
SlowShutter
Smurfs 1
Sniper 1
SongExporter 1.0.0
Soosiz 1.3
Soul
SoundJuggler 1
SpaceStation 1.3.0
SpeakOut 1
Speedtest 1.41
Spray 1.0
Stanza
StarCannon 1
StickerShootingStar2 1.0.4
StickWars 2
StickWars
StoneWars
Storycook 1
StoryCook1st 1.3
Stylish Sprint 1.2.5
Super 8™ 1.0
Super Blast 1
SuperLaser 1
SurgeonXmas 1
Talk Doc 1.1
Talking KT
Talking Rex
Talking Roby
Talking Tom
Tango 1.6.7496
TapDefense 1
TapTrace Pro 1
TapTrace
Tesla Wars
The Creeps! 1.4.8
The Parking
TheDeep 2.0
Tiki Premium 1.3.1
Tiki Totems 1
ToonPAINT 2.1
TouchMoney 2.00
TouchNum 2.20
TouchRacing
TownTalk
Traffic Rush 1.32
translator +
Trap Master 2.1
Trip Journal 6.0
TRON 1.1
Trundle 1
tvPot 1
Tweetaholic
TweetDefense 2.1.5
Twin Blades 1
TwitBird Pre 1
Uber Racer 1.2
Undercroft 1
Underworlds
UpDownV2-Idiom 2.0.4
UpDownV2-TOEIC_Lite 2.0.4
UPDOWN_JAPON_lite
UPDOWN_SA
UPDOWN_SB
UPDOWN_TOEIC
UsingBibleView 1.0
Viber 2.0.2.4187
VLC
WC2010Camera
We Rule 1.14
WhatsApp 2.6.4
WildWest 2.5
WN-Blade
WordTrans 1
World of Magic 1.0.7
WoT
Xylo-Piano 1.0
Zentomino 1.9.6
ZombieCity Pro 1
ZombieShock 1
ZombieSweeper 1.0.1
_Shift_
글로리 1.04
기억해줄께! 1.1
꾸러기메가팩 1.01
네이버 2.2.3
네이버블로그 1.2.5
네이버톡 1.0.7
노래방 검색 1
마이피플 2.3.1
미니고객센터 1.3.2
박명수 맞고
부산 지하철 1.1
부엉이
속도측정 1
쇼고객센터 1.50
숨바꼭질
스마트뱅킹 1.3.1
스프링노트
심심타파
아미워즈
아이쿠폰 2.5
아프리카 1.1.9
앨범관리 1.520
여친카메라
여행 영어 1.0.4
여행영어회화 1
영어면접
예스24
오락실너구리 1
오마이셰프
웨더톡 2.2
윙스푼맛집 2.0.5
제사상 1
주소록 백업 1.3.0
초성변환 1.3
쿡타운 1
파랑새
편리한영어 1
푸딩 카메라 1.2.3
푸딩얼굴인식
하철이 1.45
한국근대문학 1.4
한국달력 lite 1.4.5
한컴뷰어 1.5
할인의 달인 1
헤어체인지

출처 : 외계달팽 (원작자 허가받음)

소스소스
List 컨트롤을 이용하여 대량의 데이터를 표시하고자 할때 InsertItem() 으로 데이터를 막 집어넣기만 할 것인가?
만일 간단한 문자열 데이터로만 이루어져 있다면 InsertItem() 으로 그냥 집어 넣으면 될 것이다.

만일 cheatengine 을 만든다고 했을때 메모리에서 100만개의 데이터를 찾았다고 가정해보자.
이 100만개의 데이터를 리스트 컨트롤을 이용하여 표시해야하는데 이번에 만든 cheatengine의 메모리 리스트컨트롤은 너무도 화려해서 각종 이미지가 포함되어 있고, 표시되는 데이터도 연관성에 따라서 매우 많은 정보를 보여준다.
그럼 리스트 컨트롤에 100만개의 데이터를 집어넣기 위해서 100만개의 이미지(갯수만큼)와 연관 데이터를 메모리에 올려야할까?
혹 만들어야 할 프로그램이 embeded system 에서 구동해야한다면 어떻게 할 것인가?

이 문제에 대한 해답을 다음링크로부터 얻을 수 있다.
http://www.codeproject.com/KB/list/BMPList.aspx

사실 영어 실력이 딸려서 열심히 설명을 읽었지만 도통 무슨내용인지 알 수가 없다. @.@~~

실제 샘플 프로젝트를 다운 받자. 

저자가 언급한 핵심 함수 부분에 브레이크 포인트를 걸어두고 실행시켜보면

아~~~!!!!!  (띵동띵동)




간단히 요약하자면

일단 100만개의 데이터(일종의 인덱스정보)를 컴팩드한 메모리 구조로 로딩한다. (어떻게 해서든지 알아낸 데이터는 있어야하므로)
 
리스트 컨트롤에 다음과 같이 row 수 만큼만 설정한다.
// This sets the count in the list without adding any items.  This is very fast.
m_cList.SetItemCountEx((int)m_MyDataArray.GetCount(), LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL);

비록 데이터가 아주 많다고 설정하였지만 실제 ListCtrl 에 추가한것이 아니므로 메모리는 크게 잡아먹지 않는다.

이젠 화면에 표시되는 Item 수 만큼만 그때 그때 표시한다.
void CBMPListDlg::GetDispInfo(NMHDR *pNMHDR, LRESULT *pResult)
{
// 이 함수는 화면에 표시되는 Item 갯수만큼 호출된다.
// row 갯수가 10개 이고 column 이 5개 라면 총 50회만 호출된다.
// 이 함수에서는 화면에 표시해야할 이미지가 있을때 로딩한다. (파일시스템으로 부터 로딩하면 되겠죠)
// 이 함수에서 추가로 표시해야할 데이터가 있다면 이때 다시 로딩한다. (예를들어서 내가 찾은 메모리의 속성정보나 모듈이름 등등등등)
}

이렇게 하면 100만개의 데이터를 리스트 컨트롤로 표시하더라도 키값이 4byte 라면 4메가의 데이터만 필요하다!!!!!

당장 쓸건 아니지만 알아두면 좋을것 같아서 포스팅해본다~~~

윈도우 모바일에서 X버튼은 프로그램을 SDI 혹은 MDI 으로 만들어야만 보여집니다.
(물론 직접 시스템 메뉴를 넣는다면 다이얼로그에서도 보여집니다.)

언제나 간단한 프로그램만 만들던 저에겐 다이얼로그 기반으로 만든 프로그램에서 OK 버튼 처리는 매우 쉬운 문제였습니다.
단지 OnOK() 함수를 오버라이드 하면 되니까요.

하지만 SDI 에서 X버튼은 조금 다릅니다.
아니 윈도우 모바일에서 다르다는말이 맞겠군요.

일반 Windows 플랫폼의 MFC 프로그램에서는 X버튼에 대한 처리는 OnClose() 에서 오버라이드해서 처리해주면 됩니다.

하지만 윈도우 모바일에서는 X버튼을 누를 경우 다르게 동작합니다.

일단 기본적으로 윈도우 모바일에서 X버튼은 프로그램을 백그라운드로 돌려버립니다.

그런 다음에 WM_SIZE 메세지가 호출됩니다. (물론 WM_CLOSE 나 WM_DESTROY 메세지는 호출되지 않습니다)

그래서 X버튼을 눌러서 프로그램을 종료하려면 WM_SIZE 의 메세지를 받아서 다음과 같이 처리하면 됩니다.
(MainFrame 에서 처리해야합니다.)

하지만 종료할때 사용자에게 물어봐야할 경우라면?

이미 윈도우는 백그라운드로 바뀐 상태에서 WM_SIZE 메세지를 타기 때문에 메세지 박스가 표시되지 않습니다.

그래서 꽁수로 백그라운드를 못하게끔 처리하는것입니다. -_-;

뭔가 정석이 있을것 같은데 해도 해도 안되길래 이런 꽁수를 생각했습니다.

그럼 이만.. .

Windows Mobile 에서 고유번호를 알아내는 정석은 없는것 같습니다.

각 디바이스 벤더마다 알아서 시리얼 넘버를 결정하고 시리얼넘버를 보여주는 API를 제공할 수도 있고 제공하지 않을 수도 있기 때문입니다.

이곳저곳을 막 뒤지다가 발견한 소스입니다.

완벽한 시리얼 넘버를 구현할 필요가 없다면 꽁수를 써보는것을 추천하겠습니다만... 그 꽁수도 생각 나지 않아서.-_-;

다음 소스를 참고하세요.


Windows Mobile 5.0 SDK 부터는 MS 가이드라인 때문에 메뉴 구성이

새로만들기  메뉴  IME

3가지 뿐입니다. 이 것을 변경시키려고 며칠을 삽질하다가 알아낸 정보 링크를 걸어둡니다.

먼저 주 목적은 위 메뉴에서 새로만들기 메뉴를 없애거나 조작하고 싶어서 자료를 찾아보았습니다.

그러다가 발견한 m_bShowSharedNewButton = FALSE; 해주는 방법.

하지만 VS 2008 에서는 해당 변수의 선언을 찾지 못한다는 컴파일 에러가 뜹니다.

그이유는 바로 VS 2005 개발 가이드라인 때문입니다.
http://msdn.microsoft.com/en-us/library/ms838254.aspx

MS 에서 guideline 으로 위처럼 3개의 메뉴 이외에는 메뉴바에 붙이지 않도록 하겠다 라고 선포해버린거죠.

그래서 이걸 어떻게 해야하나.. 하다가 발견한 링크입니다.

http://cafe.naver.com/latem/1035

비록 원하는 메뉴를 여러개 붙일 수는 없지만 저 보기싫은 새로만들기 버튼은 조작할 수 있습니다.

이런 멋진 팁을 알려주신 분 너무 고맙습니다. (_._);

+ Recent posts