다음을 통해 공유


단일 및 다중 탭 보기

편집기에서 다양한 유형의 보기를 만들 수 있습니다. 한 가지 예는 코드 편집기 창이고, 다른 하나는 양식 디자이너입니다.

다중 탭 보기는 여러 탭이 있는 보기입니다. 예를 들어 HTML 편집기는 아래쪽에 디자인원본이라는 두 개의 탭이 있으며 둘 다 논리적 보기입니다. 디자인 보기에는 렌더링된 웹 페이지가 표시되고 원본 보기에는 웹 페이지를 구성하는 HTML이 표시됩니다.

실제 보기에 액세스

실제 보기는 각각 코드 또는 양식과 같은 버퍼에서의 데이터 보기를 나타내는 문서 보기 개체를 호스트합니다. 따라서 각 문서 보기 개체에는 실제 보기(실제 보기 문자열로 식별됨)와 일반적으로 단일 논리적 보기가 있습니다.

그러나 일부 경우에는 실제 보기에 둘 이상의 논리적 보기가 있을 수 있습니다. 일부 예는 병렬 보기의 분할 창이 있는 편집기 또는 GUI/디자인 보기와 코드 숨김 보기가 있는 양식 디자이너입니다.

편집기가 사용 가능한 모든 실제 보기에 액세스할 수 있도록 하려면 편집기 팩터리에서 만들 수 있는 각 형식의 문서 보기 개체에 대해 고유한 실제 보기 문자열을 만들어야 합니다. 예를 들어 Visual Basic 편집기 팩터리는 코드 창 및 양식 디자이너 창에 대한 문서 보기 개체를 만들 수 있습니다.

다중 탭 보기 만들기

문서 보기 개체는 고유한 실제 보기 문자열을 통해 실제 보기와 연결되어야 하지만 실제 보기 내에 여러 탭을 배치하여 다양한 방식으로 데이터를 볼 수 있도록 할 수 있습니다. 이 다중 탭 구성에서는 모든 탭이 동일한 실제 보기 문자열과 연결되지만 각 탭에는 다른 논리적 보기 GUID가 제공됩니다.

편집기용 다중 탭 보기를 만들려면 IVsMultiViewDocumentView 인터페이스를 구현한 다음 만든 각 탭에 다른 논리적 보기 GUID(LogicalViewID)를 연결합니다.

Visual Studio HTML 편집기는 다중 탭 보기가 있는 편집기의 예입니다. 디자인원본 탭이 있습니다. 이를 활성화하려면 각 탭에 다른 논리 보기를 연결합니다. 즉, 디자인 탭에 LOGICALVIEWID_TextView를 연결하고 원본 탭에 LOGICALVIEWID_Code를 연결합니다.

적절한 논리적 보기를 지정하면 VSPackage가 양식 디자인, 코드 편집 또는 코드 디버깅과 같은 특정 용도에 해당하는 보기에 액세스할 수 있습니다. 그러나 창 중 하나는 NULL 문자열로 식별되어야 하며 이는 기본 논리적 보기(LOGVIEWID_Primary)에 해당해야 합니다.

다음 표에서는 사용 가능한 논리적 보기 값 및 해당 용도를 나열합니다.

LOGVIEWID GUID 권장 용도
LOGVIEWID_Primary 편집기 팩터리의 기본/주 보기입니다.

모든 편집기 팩터리에서 이 값을 지원해야 합니다. 이 보기는 NULL 문자열을 실제 보기 문자열로 사용해야 합니다. 하나 이상의 논리적 보기를 이 값으로 설정해야 합니다.
LOGVIEWID_Debugging 디버깅 보기. 일반적으로 LOGVIEWID_DebuggingLOGVIEWID_Code와 동일한 보기에 매핑됩니다.
LOGVIEWID_Code 코드 보기 명령으로 시작된 보기.
LOGVIEWID_Designer 양식 보기 명령으로 시작된 보기.
LOGVIEWID_TextView 텍스트 편집기 보기. 이 보기는 IVsTextView에 액세스할 수 있는 IVsCodeWindow를 반환합니다.
LOGVIEWID_UserChooseView 사용자에게 사용할 보기를 선택하라는 메시지를 표시합니다.
LOGVIEWID_ProjectSpecificEditor 사용자가 "(프로젝트 기본 편집기)" 항목을 선택하면 연결 프로그램 대화 상자에 의해

OpenItem

으로 전달됩니다.

논리적 보기 GUID는 확장 가능하지만 VSPackage에 정의된 논리적 보기 GUID만 사용할 수 있습니다.

종료 시 Visual Studio는 편집기 팩터리의 GUID와 문서 창과 연결된 실제 보기 문자열을 유지하므로 솔루션을 다시 열 때 문서 창을 다시 여는 데 사용할 수 있습니다. 솔루션을 닫을 때 열려 있는 창만 솔루션(.suo) 파일에 유지됩니다. 이러한 값은 GetProperty 메서드의 propid 매개 변수에 전달된 VSFPROPID_guidEditorTypeVSFPROPID_pszPhysicalView 값에 해당합니다.

예시

이 코드 조각은 TextView 개체를 사용하여 IVsCodeWindow를 구현하는 보기에 액세스하는 방법을 보여 줍니다. 이 경우 SVsUIShellOpenDocument 서비스가 창 프레임에 대한 포인터를 가져오기 위해 OpenDocumentViaProject를 호출하고 LOGVIEWID_TextView를 요청하는 데 사용됩니다. 문서 보기 개체에 대한 포인터는 GetProperty를 호출하고 VSFPROPID_DocView 값을 지정하여 가져옵니다. 문서 보기 개체에서 QueryInterfaceIVsCodeWindow에 대해 호출됩니다. 이 경우 텍스트 편집기가 반환되므로 GetProperty 메서드에 반환된 문서 보기 개체가 코드 창이 됩니다.

HRESULT CFindTool::GotoFileLocation(const WCHAR * szFile, long iLine, long iStart, long iLen)
{
  HRESULT hr;
  if (NULL == szFile || !*szFile)
    return E_INVALIDARG;

  if (iLine == -1L)
    return S_FALSE;

  VSITEMID                  itemid;
  VARIANT                   var;
  RECT                      rc;
  IVsUIShellOpenDocument *  pOpenDoc    = NULL;
  IVsCodeWindow *           pCodeWin    = NULL;
  IVsTextView *             pTextView   = NULL;
  IVsUIHierarchy *          pHierarchy  = NULL;
  IVsWindowFrame *          pFrame      = NULL;
  IUnknown *                pUnk        = NULL;
  IVsHighlight *            pHighlight  = NULL;

  IfFailGo(CGlobalServiceProvider::HrQueryService(SID_SVsUIShellOpenDocument, IID_IVsUIShellOpenDocument, (void **)&pOpenDoc));
  IfFailGo(pOpenDoc->OpenDocumentViaProject(szFile, LOGVIEWID_TextView, NULL, &pHierarchy, &itemid, &pFrame));
  pFrame->Show();
  VariantInit(&var);
  IfFailGo(pFrame->GetProperty(VSFPROPID_DocView, &var));
  if (VT_UNKNOWN != var.vt) { hr = E_FAIL; goto Error; }
  pUnk = V_UNKNOWN(&var);
  if (NULL != pUnk)
  {
    IfFailGo(pUnk->QueryInterface(IID_IVsCodeWindow, (void **)&pCodeWin));
    if (SUCCEEDED(hr = pCodeWin->GetLastActiveView(&pTextView)) ||
        SUCCEEDED(hr = pCodeWin->GetPrimaryView(&pTextView)) )
    {
      pTextView->SetSelection(iLine, iStart, iLine, iStart + iLen);
      // uncover selection
      IfFailGo(pTextView->QueryInterface(IID_IVsHighlight, (void**)&pHighlight));
      IfFailGo(SUCCEEDED(pHighlight->GetHighlightRect(&rc)));
      UncoverSelectionRect(&rc);
    }
  }

Error:
  CLEARINTERFACE(pHighlight);
  CLEARINTERFACE(pTextView);
  CLEARINTERFACE(pCodeWin);
  CLEARINTERFACE(pUnk);
  CLEARINTERFACE(pFrame);
  CLEARINTERFACE(pOpenDoc);
  CLEARINTERFACE(pHierarchy);
  RedrawWindow(m_hwndResults, NULL, NULL, RDW_ERASE|RDW_FRAME|RDW_INVALIDATE|RDW_ALLCHILDREN);
  return hr;
}