簡體   English   中英

如何獲取窗口類名稱的長度,以便知道要分配多大的緩沖區?

[英]How do I get the length of a window class name so I know how large of a buffer to allocate?

如何預先獲取類名長度,以便將其傳遞給GetClassName()函數中的nMaxCount參數? 像控件存在的WM_GETTEXTLENGTH消息或者窗口類名是否定義了固定的大小限制? 如果是的話,這個價值是多少?

我的目標是傳遞確切的大小而不是重新分配方法(調用GetClassName()直到它返回小於其緩沖區的大小)。

我當前的實現(沒有重新分配方法):

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

string GetWindowClass(IntPtr hWnd)
{
    const int size = 256;
    StringBuilder buffer = new StringBuilder(size + 1);

    if (GetClassName(hWnd, buffer, size) == 0)
        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());

    return buffer.ToString();
}

對於此特定函數,類名限制為256個字符。 (請參閱WNDCLASSEX結構的lpszClassName成員的文檔。)因此,只需分配該大小的固定緩沖區即可完成!

為了完整起見,讓我們看一下在沒有固定大小緩沖區的情況下調用函數的更通用的解決方案。 在這種情況下,我們可以應用一個簡單的try-double-retry算法,如下所示:

  1. 好好猜測你需要多大的緩沖區,然后分配一個這么大的緩沖區。
  2. 調用該函數。 如果寫入的字符數小於提供的緩沖區的大小,則它適合返回該值。
  3. 如果字符數等於提供的緩沖區的大小,則假定該字符串已被截斷,因此緩沖區大小加倍並返回步驟2。

您可以使用以下代碼查看算法:

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int GetClassNameW(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

string GetWindowClass(IntPtr hWnd)
{
    string className = String.Empty;
    int length = 10; // deliberately small so you can 
                     // see the algorithm iterate several times. 
    StringBuilder sb = new StringBuilder(length);
    while (length < 1024)
    {
        int cchClassNameLength = GetClassNameW(hWnd, sb, length);
        if (cchClassNameLength == 0)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        else if (cchClassNameLength < length - 1) // -1 for null terminator
        {
            className = sb.ToString();
            break;
        }
        else length *= 2;
    }
    return className;
}

(設置一個斷點並逐步實際看到它的實際效果。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM