首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 靜態超連結鍵盤導航 CStaticLink:Tab 停留、焦點矩形、空白鍵啟動 URL、支援 /clr 混合模式

     編輯:關於VC++

增強經典 CStaticLink 類別,新增完整鍵盤無障礙支援:Tab 鍵切換焦點、焦點矩形視覺提示、空白鍵啟動連結(符合對話框慣例)、解決 /clr 混合模式下 ShellExecute 失效問題,附 LinkTest 範例驗證。

鍵盤支援三步驟

  1. Tab Stop 樣式:資源編輯器勾選 Static 控件 Tabstop = True(或手動加 WS_TABSTOP),使控件進入 Tab 順序。
  2. 焦點矩形繪製:處理 WM_SETFOCUS/WM_KILLFOCUS 呼叫 DrawFocusRect():
    
    void CStaticLink::DrawFocusRect() {
        CWnd* pParent = GetParent(); CRect rc;
        if (GetStyle() & (SS_BITMAP|SS_ICON|SS_ENHMETAFILE|SS_OWNERDRAW)) {
            GetWindowRect(&rc); // 圖片用視窗矩形
        } else {
            CClientDC dc(this); CString s; GetWindowText(s);
            CFont* pOld = dc.SelectObject(GetFont());
            rc.SetRectEmpty(); dc.DrawText(s, &rc, DT_CALCRECT); // 精確文字外接矩形
            dc.SelectObject(pOld); ClientToScreen(&rc);
        }
        rc.InflateRect(1,1); pParent->ScreenToClient(&rc);
        CClientDC dcParent(pParent); dcParent.DrawFocusRect(&rc); // 父視窗 DC 繪製 XOR 矩形
    }
    
    關鍵:文字項目用 DT_CALCRECT 計算緊貼矩形,避免寬大靜態控件產生巨大焦點框;繪製於父視窗 DC 以超出控件邊界。
  3. 空白鍵啟動:處理 WM_CHAR 攔截 VK_SPACE 呼叫 Navigate(),前置 WM_GETDLGCODE 回傳 DLGC_WANTCHARS 讓對話框轉發字元訊息。

/clr 混合模式 ShellExecute 失效解決方案

原因:/clr 強制多執行緒單元(MTA),ShellExecute 依賴 IShellExecuteHook(單執行緒單元 STA 專用),導致存取被拒(錯誤碼 5)。

方案一:CSTAThread 強制 STA(推薦):


class CSTAThread { public: CSTAThread() { CoInitialize(NULL); } ~CSTAThread() { CoUninitialize(); } };
// 應用程式模組 (如 MyApp.cpp) 靜態實例:
CSTAThread forceSTAThread; // 建構早於 MFC 內部 CoInitializeEx(COINIT_MULTITHREADED)

方案二:rundll32.exe 間接啟動(相容 MTA):


CString args; args.Format(_T("url.dll,FileProtocolHandler %s"), url);
ShellExecute(NULL, _T("open"), _T("rundll32.exe"), args);
缺點:無法取得錯誤回傳碼。

方案三:.NET Process.Start + [STAThread]:純 .NET 適用,MFC 難以注入屬性。

整合更新

CStaticLink 內建 CSTAThread,自動適應原生與 /clr 專案。LinkTest 範例包含托管測試對話框,驗證混合模式下超連結正常啟動瀏覽器。

Tab 順序建議

超連結宜置於 Tab 順序末尾,避免對話框啟動焦點落於商標連結、或編輯框間跳躍穿插超連結,符合使用者預期流程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved