2013-03-02 90 views
0

什麼可能導致ShowCaretSetCaretPos失敗,ERROR_ACCESS_DENIEDShowCaret和SetCaretPos與ERROR_ACCESS_DENIED失敗

我在WM_CREATE創建插入符號和顯示WM_COMMAND插入符。 我檢查了並且CreateCaret正在成功執行。

他們應該在同一個線程中運行。

我使用SetScrollInfoInvalidateRect,然後致電ShowCaret更新我的窗口內容。但我不認爲這會導致ShowCaret失敗..

相關代碼:

#define CHAR_WIDTH 7 
#define CHAR_HEIGHT 12 

case WM_CREATE: 
    CreateCaret(hWnd, NULL, CHAR_WIDTH, 2); 
    UpdateScrollbar(hWnd); // calls SetScrollInfo. initially nMin and nMax are both 0 
    return 0; 

case WM_COMMAND: 
    switch(LOWORD(wParam)) 
    { 
    case IDM_OPENFILE: 
     if (DoOpenFile(hWnd)) 
     { 
      InvalidateRect(hWnd, NULL, TRUE); 
      UpdateScrollbar(hWnd); 

      if (SetCaretPos(CHAR_WIDTH * 12, CHAR_HEIGHT - 1) == 0) 
      { 
       char ss[33]; 
       sprintf_s(ss, "DEBUG 2: %d\n", GetLastError()); 
       OutputDebugString(ss); 
      } 

      if (ShowCaret(hWnd) == 0) 
      { 
       char ss[33]; 
       sprintf_s(ss, "DEBUG 3: %d\n", GetLastError()); 
       OutputDebugString(ss); 
      } 
     } 
     break; 
    } 
    return 0; 
+0

是窗口的窗口?由調用「ShowCaret」和「SetCaretPos」的進程創建?可能的故障模式是密碼保護的屏幕保護程序。哪個版本的操作系統? – 2013-03-02 15:56:38

+0

@DavidHeffernan是我的窗口。 Windows 7 x64 – Josh 2013-03-02 15:59:37

+0

您可以在代碼中顯示您調用這些API函數的位置,並讓我們看看您的錯誤檢查代碼。 – 2013-03-02 16:07:54

回答

5

是的,你是不是正確的事情了。每個消息隊列中只有一個插入符號(換句話說,每個線程)。當另一個窗口已經有一個窗口時,您不能創建插入符號,編輯框是最有可能的情況。您必須不會創建插入符號,或直到你的窗口接收焦點,WM_SETFOCUS消息顯示它。你必須窗口失去焦點,WM_KILLFOCUS消息摧毀它。

您使用GetLastError()的方式也很危險,雖然你可能逃脫它現在。以C或C++評估參數的順序不是確定性的。您冒着改變錯誤代碼的參數表達式之一的風險。在調用其他任何東西之前總是獲取錯誤代碼,將其存儲在局部變量中。

an 從來沒有跳過錯誤檢查,至少你必須斷言()返回值。 CreateCaret()調用可能現在失敗,因爲剛剛創建的窗口永遠不會有焦點。