2013-11-01 1 views
2

첫째 :
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644952%28v=vs.85%29.aspx변환 C++ 코드 : SendMessageTimeout() SendMessageTimeout에 대한 모든 다큐의

내가이 C++ 코드를 가지고 내가 C 번호로 변환하려는 : 내가 무슨 짓을

LRESULT success = SendMessageTimeout(
    HWND_BROADCAST, 
    WM_SETTINGCHANGE, 
    0, 
    (LPARAM) "Environment", 
    SMTO_ABORTIFHUNG, 
    5000, 
    NULL 
); 

in C# :

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    public static extern IntPtr SendMessageTimeout(
     IntPtr hWnd, 
     uint Msg, 
     UIntPtr wParam, 
     IntPtr lParam, 
     uint fuFlags, 
     uint uTimeout, 
     out UIntPtr lpdwResult 
    ); 

    SendMessageTimeout(
     (IntPtr)0xFFFFFFFF, //HWND_BROADCAST 
     0x001A,    //WM_SETTINGCHANGE 
     (UIntPtr)0, 
     (IntPtr)"Environment", // ERROR_1: can't convert string to IntPtr 
     0x0002,    // SMTO_ABORTIFHUNG 
     5000, 
     out UIntPtr.Zero  // ERROR_2: a static readonly field can not be passed ref or out 
    ); 
+0

봐 그래서 당신이 그것을 사용하려는 방법과 호환 다른 공예. 마지막 부분은 로컬을 정의하고 전달하십시오. – Warty

답변

5

  1. HWND_BROADCAST0xFFFF하지
  2. 0xFFFFFFFF 수동 Marshal.StringToHGlobalUni를 사용하여 LPARAM 값으로 메모리를 할당하고 Marshal.FreeHGlobal를 사용하여 호출 후 그것을 해제해야합니다. 이 메모리를 비우면 누출됩니다. Marshal 된 메모리는 가비지 수집되지 않습니다.
  3. lpdwResult의 경우 변수를 만들고 IntPtr을 전달하면됩니다. 값은 무시할 수 있습니다. 당신은 당신이 들어 왔는지 창이 어떤 작업을 수행하는지 모르는 이후 SendMessage 호출에 전달 메모리를 해제 할 때주의해야 일반적으로

    IntPtr result = IntPtr.Zero; 
    IntPtr setting = Marshal.StringToHGlobalUni("Environment"); 
    
    SendMessageTimeout(
        (IntPtr)0xFFFF,  //HWND_BROADCAST 
        0x001A,    //WM_SETTINGCHANGE 
        (UIntPtr)0, 
        (IntPtr)setting, 
        0x0002,    // SMTO_ABORTIFHUNG 
        5000, 
        out result 
    ); 
    
    Marshal.FreeHGlobal(setting); 
    

    :

코드는 다음과 같이해야한다 포인터를 전달하십시오. Howerver WM_SETTINGCHANGE이 Windows 메시지에 내장되어 있기 때문에 Windows에서이 포인터를 처리합니다.

+1

안녕하세요, 변경 사항을 적용하려면 시스템을 재부팅하지 않아도됩니다. 하지만 CMD/Powershell을 다시 시작해야합니다. 이것도 방지하는 방법을 알고 있습니까? –

5

SendMessage는 사용하지 않는 인수 유형으로 인해 약간 고통 스럽습니다. 많은 일을해야하기 때문에 필요합니다. C 언어에서는 필요하지만 C#에서는 필요하지 않습니다. 여기에서 원하는 것은 오버로드를 지원하는 C# 언어를 이용하는 것입니다. IntPtr 인수는 참조 유형 참조 일 수 있습니다. pinvoke marshaller는이를 포인터로 올바르게 변환하고 메모리 관리 번거 로움을 처리합니다.

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
public static extern IntPtr SendMessageTimeout(
    IntPtr hWnd, 
    int Msg, 
    IntPtr wParam, 
    string lParam, 
    int fuFlags, 
    int uTimeout, 
    IntPtr lpdwResult 
); 

는 이제 사용할 수 있습니다 : Marshal.StringToHGlobalUni + FreeHGlobal 대 C-문자열을 마샬링에

SendMessageTimeout((IntPtr)0xffff, 0x001A, IntPtr.Zero, "Environment", 
        2, 5000, IntPtr.Zero);