Create TOC

레이블이 win32인 게시물을 표시합니다. 모든 게시물 표시
레이블이 win32인 게시물을 표시합니다. 모든 게시물 표시

2016년 10월 11일

Vim 8.0/Win32에서 vim-signify 오류 수정

한글 Windows 7 환경에서 Vim 8.0 x64 빌드를 사용할 경우 vim-signify 플러그인에서 오류가 발생한다.

lang mes C를 해도 메시지가 한글로 표시되기 때문에 나타나는 문제이다. 아래와 같이 소스를 수정해주면 문제가 해결된다.

diff --git a/autoload/sy/fold.vim b/autoload/sy/fold.vim
index 35028d8..a51ef54 100644
--- a/autoload/sy/fold.vim
+++ b/autoload/sy/fold.vim
@@ -100,7 +100,11 @@ function! s:get_lines() abort

   let lines = []
   for line in split(signlist, '\n')[2:]
-    call insert(lines, matchlist(line, '\v^\s+line\=(\d+)')[1], 0)
+    let tokens = matchlist(line, '\v^\s+line\=(\d+)')
+    if 0 == len(tokens)
+      let tokens = matchlist(line, '\v^\s+줄\=(\d+)')
+    endif
+    call insert(lines, tokens[1], 0)
   endfor

   return reverse(lines)
diff --git a/autoload/sy/sign.vim b/autoload/sy/sign.vim
index 6af68ff..2cd818b 100644
--- a/autoload/sy/sign.vim
+++ b/autoload/sy/sign.vim
@@ -30,9 +30,11 @@ function! sy#sign#get_current_signs() abort
     silent! execute 'sign place buffer='. b:sy.buffer
   redir END
   silent! execute 'language message' lang
-
   for signline in split(signlist, '\n')[2:]
     let tokens = matchlist(signline, '\v^\s+line\=(\d+)\s+id\=(\d+)\s+name\=(.*)$')
+    if 0 == len(tokens)
+      let tokens = matchlist(signline, '\v^\s+줄\=(\d+)\s+id\=(\d+)\s+이름\=(.*)$')
+    endif
     let line   = str2nr(tokens[1])
     let id     = str2nr(tokens[2])
     let type   = tokens[3]

수정 후 fold.vimcp949, sign.vimutf-8로 저장해야 한다.

Vim/Win32 메뉴 표시 언어를 영어로 고정

아래와 같은 내용을 _vimrc에 추가한다.


if has('win32')
 lan mes en_US
 if has('menu') && has('multi_lang') && has('gui_running')
  set langmenu=en_US
  source $ViMRUNTIME/delmenu.vim
  source $ViMRUNTIME/menu.vim
 endif
endif

2016년 7월 11일

Vim/Win32에서 CtrlSF 가 동작하지 않을때

Windows환경의 Vim x64에서 CtrlSF 플러그인이 동작하지 않으면 아래와 같이 shellescape을 적당히 바꾸어 준다.

--- a/autoload/ctrlsf/backend.vim
+++ b/autoload/ctrlsf/backend.vim
@@ -110,7 +110,11 @@ func! s:BuildCommand(args) abort
     endif
 
     " pattern (including escape)
-    call add(tokens, shellescape(ctrlsf#opt#GetOpt('pattern')))
+    if has('win32')
+  call add(tokens, '"' . ctrlsf#opt#GetOpt('pattern') . '"')
+ else
+  call add(tokens, shellescape(ctrlsf#opt#GetOpt('pattern')))
+ endif
 
     " path
     call extend(tokens, ctrlsf#opt#GetPath())
--- a/autoload/ctrlsf/opt.vim
+++ b/autoload/ctrlsf/opt.vim
@@ -139,7 +139,11 @@ func! ctrlsf#opt#GetPath() abort
             let resolved_path = expand(path, 0, 1)
 
             for r_path in resolved_path
-                call add(path_tokens, shellescape(r_path))
+    if has('win32')
+     call add(path_tokens, '"' . r_path . '"')
+    else
+     call add(path_tokens, shellescape(r_path))
+    endif
             endfo
         endfo
     else
@@ -151,7 +155,11 @@ func! ctrlsf#opt#GetPath() abort
         if empty(path)
             let path = expand('%:p')
         endif
-        call add(path_tokens, shellescape(path))
+  if has('win32')
+   call add(path_tokens, '"' . path . '"')
+  else
+   call add(path_tokens, shellescape(path))
+  endif
     endif
 
     return path_tokens

2014년 2월 4일

Vim/Win32에서 VCSCommand가 'no suitable plugin' 오류를 내면서 동작하지 않을 때

Windows 7 x64에서 64bit로 빌드된 vim을 사용 중인데 VCSCommand로 svn을 사용하려고 하면 'no suitable plugin' 오류가 발생한다.

원인은 외부 명령 실행시 'svn' info . 식으로 실행 명령에 ' 가 붙기 때문인데 vcssvn.vim 파일을 수정한다.

--- a/plugin/vcssvn.vim
+++ b/plugin/vcssvn.vim
@@ -72,6 +72,9 @@ let s:svnFunctions = {}
 " Returns the executable used to invoke git suitable for use in a shell
 " command.
 function! s:Executable()
+       if has ('win32')
+               return VCSCommandGetOption('VCSCommandSVNExec', 'svn')
+       endif
        return shellescape(VCSCommandGetOption('VCSCommandSVNExec', 'svn'))
 endfunction

vcssvn.vim을 수정하면 'no suitable plugin' 오류는 나지 않지만 VCSInfo 등의 명령을 실행할 때 파일 명에 ' 가 붙어서 실패하게 된다.

이 문제는 vcscommand.vim을 수정해야 한다.

--- a/plugin/vcscommand.vim
+++ b/plugin/vcscommand.vim
@@ -1235,7 +1235,11 @@ function! VCSCommandDoCommand(cmd, cmdName, statusText, options)
     if match(a:cmd, '<VCSCOMMANDFILE>') > 0
         let fullCmd = substitute(a:cmd, '<VCSCOMMANDFILE>', fileName, 'g')
     else
-        let fullCmd = a:cmd . ' -- ' . shellescape(fileName)
+        if has ('win32')
+            let fullCmd = a:cmd . ' -- "' . fileName .'"'
+        else
+            let fullCmd = a:cmd . ' -- ' . shellescape(fileName)
+        endif
     endif

     " Change to the directory of the current buffer.  This is done for CVS, but

2014년 1월 6일

Vim/Win32환경에서 한글이 포함된 경로의 파일에 대해 python mode가 동작하지 않는 문제

Win32환경에서 한글이 포함된 경로의 python 파일에 대해 python mode 확장이 제대로 동작하지 않는다.

vundle을 사용할때 기준으로 ~/.vim/bundle/python-mode/pymode/environment.py 파일을 수정해야 한다.

아래는 patch 내용이다.

--- pymode/environment.py_org    2014-01-06 08:44:00.971905800 +0900
+++ pymode/environment.py    2014-01-06 09:21:12.068213500 +0900
@@ -6,6 +6,7 @@
 import json
 import time
 import os.path
+import platform

 from .utils import PY2

@@ -199,11 +200,19 @@

         """

-        if dumps:
-            value = json.dumps(value)
+        if platform.system() != 'Windows':
+            if dumps:
+                value = json.dumps(value)
+
+            if PY2:
+                value = value.decode('utf-8').encode(self.options.get('encoding'))
+        else:
+            # win32 patch
+            if dumps:
+                value = json.dumps(value, ensure_ascii=False, encoding='cp949').encode('cp949')

-        if PY2:
-            value = value.decode('utf-8').encode(self.options.get('encoding'))
+            if PY2:
+                value = value.decode('cp949').encode(self.options.get('encoding'))

         return value
environmemt-win32.path

2009년 5월 19일

Python/py2exe를 이용해서 win32 binary를 만들때 manifest 추가

Windows 환경에서 py2exe 를 이용해서 exe를 만들때 manifest 를 추가할 수 있다.

setup.py를 아래와 같이 만든다.

manifest = """
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <asmv3:trustInfo xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
    <asmv3:security>
      <asmv3:requestedPrivileges>
        <asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </asmv3:requestedPrivileges>
    </asmv3:security>
  </asmv3:trustInfo>
</assembly>
"""

setup(name='MyApp',
    #...
    windows=[ { #...
        'other_resources':[(24, 1, manifest)],
    }]
)

2008년 9월 20일

Win32/프로세스 실행 방법에 따른 argument 해석

프로세스 실행 방법에 따라서 argument 해석이 어떻게 달라지는지 간단한 테스트를 수행했다.

테스트

프로세스를 실행시킬 수 있는 API중 ShellExecuteEx()와 CreateProcess() 에 대해서 테스트를 수행한다. 실행시 인자는 "12345"를 사용한다.

ShellExecuteEx

입력

인자
SHELLEXECUTEINFO::lpFileC:\Test\MyTest.exe
SHELLEXECUTEINFO::lpParameters12345

결과

argument를 얻는 방법결과
CWinApp::m_lpCmdLine12345
GetCommandLineW()"C:\Test\MyTest.exe" 12345
argc2
argv[0]C:\Test\MyTest.exe
argv[1]12345

CreateProcess 1

입력

lpApplicationNameNULL
lpCommandLine"C:\Test\MyTest.exe" 12345

결과

argument를 얻는 방법결과
CWinApp::m_lpCmdLine12345
GetCommandLineW()"C:\Test\MyTest.exe" 12345
argc2
argv[0]C:\Test\MyTest.exe
argv[1]12345

CreateProcess 2

입력

lpApplicationNameC:\Test\MyTest.exe
lpCommandLine"C:\Test\MyTest.exe" 12345

결과

argument를 얻는 방법결과
CWinApp::m_lpCmdLine12345
GetCommandLineW()"C:\Test\MyTest.exe" 12345
argc2
argv[0]C:\Test\MyTest.exe
argv[1]12345

CrateProcess 3

입력

lpApplicationNameC:\Test\MyTest.exe
lpCommandLine12345

결과

argument를 얻는 방법결과
CWinApp::m_lpCmdLine
GetCommandLineW()12345
argc1
argv[0]12345

결론

  1. 프로세스를 실행할때는 가급적 ShellExecuteEx() API를 사용한다.
  2. CreateProcess() API를 사용할 때는 lpCommandLine 인자에 전체 명령행을 완성해서 전달한다.

error LNK2005

MFC 와 runtime library의 링크 순서가 잘못될 경우 아래와 같은 메시지를 볼 수 있습니다.

mfc42u.lib(dllmodul.obj):error LNK2005: _DllMain@12 already defined in MSVCRT. lib(dllmain.obj)

해결책은 아래와 같습니다. (VC6 기준)

  1. Project 메뉴에서 Settings를 누릅니다.
  2. Project Settings 대화 상자의 Settings For 에서 링크 오류가 발생하는 프로젝트 구성을 선택합니다.
  3. Link 탭의 Category 콤보 상자에서 Input을 선택합니다.
  4. Ignore libraries 상자에 msvcrt.lib 를 삽입합니다.
  5. Object/library modules 상자에 라이브러리 mfcs42u.lib msvcrt.lib 를 삽입합니다.

http://support.microsoft.com/kb/148652

2007년 11월 18일

To create a notification thread and then return

int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {

    // Create our events for event logging notification as well as our event for ending the notification thread
    g_evtNewEventLogRecord = CreateEvent(NULL, TRUE, FALSE, NULL);
    HANDLE hThread = chBEGINTHREADEX(NULL, 0, EventNotifyThread, NULL, 0, NULL);

    DialogBox(hinstExe, MAKEINTRESOURCE(IDD_EVENTMONITOR), NULL, Dlg_Proc);

    // Clean up
    QueueUserAPC(DoNothingAPC, hThread, NULL);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(g_evtNewEventLogRecord);
    CloseHandle(hThread);
    return(0);
}

///////////////////////////////////////////////////////////////////////////////
DWORD WINAPI EventNotifyThread(PVOID pvParam) {

    // Note that this is not the thread that called NotifyChangeEventLog.
    // The main thread does this in response to the WM_INITDIALOG message.
    // If the main thread were to terminate before this thread, then
    // notifications would cease to function. However, since it will always
    // terminate after this thread, then we can count on the notification event
    // working properly.

    // Wait for an event notification or for APC altering this thread to termiante.
    while (WaitForSingleObjectEx(g_evtNewEventLogRecord, INFINITE, TRUE) != WAIT_IO_COMPLETION) {
        FORWARD_WM_USERNOTIFYUPDATE(g_hwnd, PostMessage);
    }

    // We got an APC, this thread should terminate
    return(0);
}

Comparing Memory Allocation Methods

This topic provides a brief comparison of the following memory allocation methods:

  • CoTaskMemAlloc
  • GlobalAlloc
  • HeapAlloc
  • LocalAlloc
  • malloc
  • new
  • VirtualAlloc

The following functions are equivalent: GlobalAlloc, LocalAlloc, and HeapAlloc with the handle returned by the GetProcessHeap function.

The VirtualAlloc function allows you to specify additional options for memory allocation. However, its allocations use a page granularity, so using VirtualAlloc can result in higher memory usage.

The malloc function has the disadvantage of being run-time dependent. The new operator has the disadvantage of being compiler dependent and language dependent.

The CoTaskMemAlloc function has the advantage of working well in either C, C++, or Visual Basic. It is also the only way to share memory in a COM-based application, since MIDL uses CoTaskMemAlloc and CoTaskMemFree to marshal memory.

Windows 2000 에서 Network 설정 변경

Win2k 에서 Network 설정 변경

  • INetCfg COM 사용
  • INetCfg COM 사용2
  • WMI 사용
  • Q162771: Installing Network Components Without the Control Panel
  • Q185783: SAMPLE: IPInst.exe Determines Whether TCP/IP is Installed
  • Q120642: TCP/IP & NBT Configuration Parameters for Windows NT

2007년 2월 5일

Win32/Critical section에 대한 몇 가지 주의 사항

시스템 가용 메모리 부족시

문제

InitializeCriticalSection()함수를 이용해서 만들어진 critical section은 시스템의 가용메모리가 부족하면 EnterCriticalSection()할때 system exception이 발생하게 된다.

해결

InitializeCriticalSection() 함수 대신 InitializeCriticalSectionAndSpinCount() 함수를 사용한다. 단순하게 SEH를 사용하면 될 것 같지만 SEH는 문제를 해결해 주기 보다는 감추는 경우가 많기 때문에 되도록 사용하지 않는 것이 좋다.

Vista에서 제한점

critical section으로 lock걸린 구역안에서 Sleep() 함수를 사용하면 안된다.

2006년 11월 27일

Vista 개발 관련 링크들

vista 관련 자료 저장용

Complete list of Windows Vista API changes

New_Windows_Vista_APIs.zip

  • http://devreadiness.org/files/5/white_papers/entry137.aspx
  • http://devreadiness.org/files/137/download.aspx

Microsoft Windows Vista Compatibility Document

ISV_Windows_Vista_Compatibility_cookbook.zip

  • http://devreadiness.org/files/5/white_papers/entry10.aspx

Vista compatibility investigation guide

  • http://devreadiness.org/files/5/white_papers/entry125.aspx

Windows Vista UAC Development Requirements

  • http://devreadiness.org/files/5/white_papers/entry158.aspx

Application testing guidelines for Windows Vista

  • http://devreadiness.org/files/5/presentations/entry131.aspx

Windows Vista Backup and Application Compatibility

  • http://devreadiness.org/files/5/white_papers/entry157.aspx

Links

  • http://blogs.msdn.com/vistacompatteam/default.aspx

2006년 3월 8일

인터넷 연결상태 알아오기


DWORD dwConnectionTypes;
if(InternetGetConnectedState(&dwConnectionTypes, 0)) // 정상적으로 검사됨
{
	if((dwConnectionTypes & INTERNET_CONNECTION_MODEM) != 0)
		printf("Internet connection using modem");

	if((dwConnectionTypes & INTERNET_CONNECTION_LAN) != 0)
		printf("Internet connection using LAN");

	if((dwConnectionTypes & INTERNET_CONNECTION_PROXY) != 0)
		printf("Internet connection using Proxy");

	if((dwConnectionTypes & INTERNET_CONNECTION_MODEM_BUSY) != 0)
		printf("Modem is busy");

	if((dwConnectionTypes & INTERNET_RAS_INSTALLED) != 0)
		printf("RAS is installed");

	if((dwConnectionTypes & INTERNET_CONNECTION_OFFLINE) != 0)
		printf("Offline");
}
else
	printf("InternetGetConnectedState() API is failed!");

Windows Icon Cache를 다시 생성하기

가끔 Windows Icon Cache 가 깨져서 다시 생성해야 할 필요가 있다. 보통은 icon cache 파일을 삭제후 재부팅 하거나 바탕화면 등록 정보에서 icon 크기를 바꾸면 된다.

아래 코드는 바탕화면 icon 크기를 변경시켜서 icon cache를 다시 생성하게 만드는 코드이다.

#include <atlbase.h>

/**	@brief	윈도우의 아이콘 캐쉬를 다시 빌드한다.
 *
 *	@author	Yun-yong Choi
 */
void __cdecl RebuildIconCache(void)
{
	CRegKey RegKey;		/**< registry interface */
	int OldSize = 0;	/**< 원래 shell icon 크기를 저장 */

	LRESULT lRet = RegKey.Open(HKEY_CURRENT_USER,
		"Control Panel\\Desktop\\WindowMetrics",
		KEY_ALL_ACCESS);

	if (lRet == ERROR_SUCCESS)
	{
		DWORD dwCnt;
		CHAR buf[BUFSIZ] = {0, };

		dwCnt = BUFSIZ - 1;

		lRet = RegKey.QueryValue(buf, "Shell Icon Size", &dwCnt);
		if (lRet != ERROR_SUCCESS)
		{
			RegKey.Close();
			return;
		}

		OldSize = atoi(buf);
		wsprintf(buf, "%ld", OldSize + 1);
		RegKey.SetValue(buf, "Shell Icon Size");
		SendMessage( HWND_BROADCAST, WM_SETTINGCHANGE,
			SPI_SETICONMETRICS, (LPARAM)( "WindowMetrics" ));

		if (OldSize > 0)
		{
			wsprintf(buf, "%ld", OldSize);
			RegKey.SetValue(buf, "Shell Icon Size");

			SendMessage( HWND_BROADCAST, WM_SETTINGCHANGE,
				SPI_SETICONMETRICS, (LPARAM)( "WindowMetrics" ));
		}
		else
		{
			RegKey.DeleteValue("Shell Icon Size");

			SendMessage( HWND_BROADCAST, WM_SETTINGCHANGE,
				SPI_SETICONMETRICS, (LPARAM)( "WindowMetrics" ));
		}
		RegKey.Close();
	}
}

2002년 10월 20일

Win32/Unicode Programming

Unicode 로 작성된 program의 동작 되지 않는 OS

  • Windows 95
  • Windows 98작동을 위하여서는 Windows program install이 필요함.

TCHAR의 형태를 활용한다.

UNICODE와 MBCS에서 같은 Source를유지하기 위하여 tchar.h의 TCHAR를 활용한다.

변경 전변경 후
charTCHAR
unsigned charTBYTE
char str[] = "test string"TCHAR str[] = TEXT("test string")

함수를 변경한다.

변경 전변경 후
strlen()_tcslen() * sizeof(TCHAR)
strcat()_tcscat()
strcpy()_tcscpy()
str...()_tcs...()

Unicdoe define 설정방법

_MBCS대신에 _UNICODE를 정의 한다. 일부 crt 프로그램의 경우 UNICODE define을 추가로 필요로 한다. MFC에서는 _UNICODE나 UNICODE중 하나만 define되어 있으면 된다.

MFC Application Unicode compile경우 link " _WinMain@16"의 Error가 발생한다.

Link->Output에서 Entry-point symbol 을 미지정 상태에서 ""에서 "wWinMainCRTStartup"으로 설정한다.

함수의 인자가 char*인경우

GetProcAddress(HMODULE, LPCSTR) 에서 두번째의 인자는 LPCSTR이므로 _T("")를 사용하지 않는다.

::GetProcAddress(hModuel, _T("function name"));  // no
::GetProcAddress(hModuel, "function name");      // ok

TCHAR의 형태를 지원하지 않는 함수 목록

atof (atoi, atol은 지원)

Unicode text file

unicode로 text파일을 만들때 편집기에 따라서 파일의 처음 부분에 2byte가 BOM 값을 가지는 경우가 있다. 따라서 text파일을 처리할 때 BOM 처리에도 주의해야 한다.

특별한 처리 없이 BOM이 있는 파일을 ftscanf 계열의 함수를 사용해서 처리하면 Unicode compile에서는

  • MBCS text 파일을 읽을경우 -> Unicode로 변경하여 read (O)
  • Unicode text 파일을 읽을경우 -> Unicode로 read (O)

MBCS compile에서는

  • MBCS text 파일을 읽을경우 -> MBCS로 read (O)
  • Unicode text 파일을 읽을경우 -> 잘못된 읽기(처음 한자만 읽고 다음 글자를 null로 인식하여, 한자만 읽힌다.)

결국 BOM이 포함된 text 파일을 다룰 경우 Unicode compile을 하는 것이 좋다.

9X 지원의 여부

9x에서는 Unicode 지원에 문제가 있다. 대부분의 Unicode 함수는 compile과 실행이 되나 return값이 FALSE가 나온다. 공통의 code에서는 LoadStringW(), CreateRegistryW()등이다. (windows api 계열)

wstrcpy()는 정상 동작한다. (c run-time 계열)