MSDN Library (April 2003) a Visual C++ 6.0

Autor: Jiří Valerian

Již 15.dubna 2003 byla mimo jiné na http://www.cdr.cz/ zveřejněna informace o odkazech umožňujících volné stažení MSDN Library (April 2003). Článek je na adrese http://www.cdr.cz/a/novinky/starsi/339 pod názvem Stáhněte si od Microsoftu MSDN Library.

Jedná se o tři obrazy CD (3x650MB) tj. o ISO soubory k vypálení CD. V době psaní tohoto článku jsou odkazy ještě stále funkční viz níže.

http://download.microsoft.com/download/b/d/c/bdccea1b-96d9-4ad9-8045-56619af95835/qtr40enud1.img
http://download.microsoft.com/download/b/d/c/bdccea1b-96d9-4ad9-8045-56619af95835/qtr40enud2.img
http://download.microsoft.com/download/b/d/c/bdccea1b-96d9-4ad9-8045-56619af95835/qtr40enud3.img

Po stažení výše zmíněných souborů, vypálení na CD a následné full instalaci to "sežralo" pěkných cca 1.8 GB místa na HDD :o). MSDN je funkční pokud se spustí ručně, ale nefunguje přes F1 z Visual C++ 6.0. Po stisku F1 se zobrazí hlášení:

The MSDN collection does not exist. Please reinstall MSDN.

Je to způsobeno tím, že předchozí MSDN Library jsem odinstaloval (bylo z roku 2001) a nové MSDN již je v jiném formátu, který se starým dobrým Visual C++ 6.0 moc nespolupracuje. Po delším hledání na Internetu jsem se nakonec rozhodl pro vlastní řešení tohoto problému jehož postup dále uvádím.

Vše bylo realizováno ve Windows XP Professional. Jistě se najdou i jiná možná i jednodušší a elegantnější řešení, ale toto se mi nakonec zdálo jako nejschůdnější a protože to fungovalo tak jsem se již jinou variantou nezabýval :o).

Zde je popis řešení

Řešení předpokládá, že již je v systému instalován Windows Script Host, který je u Windows XP již součástí instalace systému. Pokud jej nemáte pak se dá stáhnout na serveru Microsoftu viz odkaz:

http://msdn.microsoft.com/downloads/list/webdev.asp?frame=true

Nejprve jsem si ve Visual C++ 6.0 vytvořil jednoduchou Win32 aplikaci pro spouštění MSDN viz níže uvedený zdroják:.

#include <windows.h>

bool UplynulTimeout (DWORD StartTick, DWORD Timeout)
{
  if ((GetTickCount() - StartTick) >= Timeout) return true;
  return false;
};

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  if (lpCmdLine) {
    DWORD StartTick;
    DWORD dwThreadID;
    DWORD dwCurrentThreadID;
    HWND  hWnd;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si,sizeof(STARTUPINFO));
    ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWNORMAL;
    CreateProcess(NULL,lpCmdLine,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
    StartTick = GetTickCount();
    while (true) {
      Sleep(1000);
      hWnd = FindWindow("wndclass_desked_gsk",NULL);
      if (hWnd) {
        dwThreadID = GetWindowThreadProcessId(hWnd,NULL);
        dwCurrentThreadID = GetCurrentThreadId();
        if (dwThreadID != dwCurrentThreadID) {
          if (AttachThreadInput(dwCurrentThreadID,dwThreadID,TRUE)) {
            if (IsIconic(hWnd)) ShowWindow(hWnd,SW_RESTORE);
            SetForegroundWindow(hWnd);
            SetFocus(hWnd);
            AttachThreadInput(dwCurrentThreadID,dwThreadID,FALSE);
            break;
          };
        };
      };
      if (UplynulTimeout(StartTick,30000L)) break;
    };
  };
  return 0;
};

Aplikace má název RunMsdn.exe a po překladu jsem exáč překopíroval do systémového adresáře Windows. Poté jsem si ve Visual C++ vytvořil níže uvedené makro. Makra se dají v IDE Visual C++ 6.0 vytvářet například přes volbu menu Tools -> Macro...

Vytvoření makra

a po zobrazení dialogu stačí do napsat název nového makra např. ShowMSDN


poté kliknout na tlačítku Edit a v dalším dialogu Add Macro


můžete doplnit popis třeba: Zobrazit MSDN nápovědu (Ctrl+F1) a uzavřít jej tlačítkem OK. Poté se otevře editace nového makra. Pak už jen stačí vložit níže uvedený kód makra s tím, že pokud máte náhodou dexplore.exe nainstalován jinde tak si opravte cestu, ale pokud jste to instalovali z CD MSDN Library (April 2003) tak to bude nejspíš stejné.

Sub ShowMSDN()
'DESCRIPTION: Zobrazit MSDN nápovědu (Ctrl+F1)
  Dim Zvoleno
  Dim Path 
  Dim oShell
  Zvoleno = ActiveDocument.Selection
  Cesta = "RunMsdn.exe " + _
          chr(34) + _
          "C:\Program Files\Common Files\Microsoft Shared\Help\dexplore.exe " + _
	   chr(34) + _
	   "/helpcol ms-help://MS.MSDNQTR.2003APR.1033 /filter " + _
	   chr(34) + _
	   "Platform SDK" + _
	   chr(34)
  Set oShell = CreateObject ("WSCript.shell")
  oShell.Run Cesta, 1, true
  If Zvoleno = "" Then
	ActiveDocument.Selection.WordRight
	ActiveDocument.Selection.WordLeft
	ActiveDocument.Selection.WordRight dsExtend
    Zvoleno = ActiveDocument.Selection
    ActiveDocument.Selection.CharLeft
  End If
  If Zvoleno <> "" Then
    oShell.SendKeys("^(%{F2})")
    oShell.SendKeys(Zvoleno)
    oShell.SendKeys("{ENTER}")
  End If
  Set oShell = Nothing
End Sub

Poté nezapomeňte před uzavřením souboru maker změnu uložit. Nakonec ještě musíte přiřadit novému makru klávesovou zkratku. Já jsem použil volnou zkratku Ctrl+F1.

Přiřazení klávesové zkratky lze provést v IDE Visual C++ 6.0 volbou z menu Tools -> Customize...


v zobrazeném dialogu zvolit záložku Keyboard v combu pod názvem Category zvolit položku Macros. V combu pod názvem Editor by měla být zvolena položka Text. Následně v seznamu pod názvem Commands zvolit položku dle názvu nového makra tj. v tomto případě ShowMSDN a přepnout myší na editaci tak, aby blikal textový kurzor v editačním poli pod názvem Press new shortcut key.


Poté stisknout klávesovou zkratku Ctrl+F1 a kliknout myší na tlačítku Assign a nakonec dialog uzavřít tlačítkem Close. Nyní již můžete vyzkoušet funkčnost. Ve zdrojáku otevřeném v IDE Visual C++ 6.0 se postavte kurzorem třeba na začátek nebo doprostřed slova např. AttachThreadInput a poté stiskněte klávesovou zkratku Ctrl+F1.

Napoprvé po editaci makra se Vám pravděpodobně zobrazí následující hlášení:


Dialog hlášení uzavřete tlačítkem Ano. Pokud nebudete provádět další změny v makrech pak se toto hlášení již zobrazovat nebude. Po uzavření dialogu hlášení bude provedeno makro ShowMSDN. Než se vše provede tak to pár vteřin trvá. Prohlížeč MSDN není žádný velký rychlík :o) a v závislosti na výkonu mašiny to může trvat i pár desítek vteřin. Na mém Celeronu 400 MHz s 200 MB RAM to ve Windows XP Professional najede cca do 10 až 15 vteřin.

Po provedení makra je zobrazeno okno MSDN nápovědy, v něm je zvolena sekce Index a v ní je v poli Look for: uvedeno slovo AttachThreadInput a v pravé části je k němu rovnou zobrazen podrobný popis z MSDN nápovědy z oddílu Platform SDK

Rešení, které jsem uvedl má dva drobné nedostatky :o).

  1. Prvním nedostatkem je skutečnost, že MSDN prohlížeč se volá s parametrem /filter "Platform SDK" a tudíž pokud budete hledat například info k nějaké třídě MFC, třeba CString tak se najde a zobrazí názvem podobné téma, které se nalezne v sekci Platform SDK tj. v daném případě namísto CString to je CStreamingSound Sample Class. Tento nedostatek se dá považovat za částečně vyřešený tím, že se v makru použije jako typ filtru "Visual C++", který zahrnuje:

  2. Druhým nedostatkem je to, že se vždy otvírá nové okno prohlížeče MSDN. Důvod - nezjistil jsem syntaxi Topicu a Itemu pro volání prohlížeče MSDN přes DDE (pozn. nejsem si vůbec jist, zda tento způsob volání tj. přes DDE nový MSDN prohlížeč vůbec podporuje). Pokud by se to někomu podařilo zjistit, dejte vědět.

Poznámka (L. Zezula): Můžete si také stáhnout zdrojový text vylepšené verze, která neotevírá vždy nové okno. V balíčku jsou přiložena i upravená makra.

Řešení s využitím ActiveX

Jiná možnost je využití ActiveX, která je prohlížečem MSDN podporována. Použití ActiveX ve skriptu odstraní některé nedostatky, které byly v předchozích řešeních. Zde je zápis skriptu:

Public oHelp

Sub ShowMSDNIndex()
    'DESCRIPTION: Show MSDN-Index with selected word (F1)
    Dim sSelection
    Dim oShell

    sSelection = ActiveDocument.Selection
    If sSelection = "" Then
        ActiveDocument.Selection.WordRight
        ActiveDocument.Selection.WordLeft
        ActiveDocument.Selection.WordRight dsExtend
        sSelection = ActiveDocument.Selection
        ActiveDocument.Selection.CharLeft
    End If

    On Error Resume Next
    Set oHelp = GetObject (,"DExplore.AppObj")
    
    If oHelp Is Nothing Then
        Set oHelp = CreateObject ("DExplore.AppObj")
    End If

    If Not oHelp Is Nothing Then
        oHelp.SetCollection "ms-help://MS.MSDNQTR.2004JAN.1033", "Visual C++"
        oHelp.Index
        
     If sSelection <> "" Then
         oHelp.DisplayTopicFromF1Keyword sSelection
     End If
        
     'Activate the MSDN application
     Set oShell = CreateObject("WScript.shell")
     oShell.AppActivate "MSDN Library"
     Set oShell = Nothing
    End If
End Sub

Když jsem makro přiřadil na klávesu F1, fungovalo to dobře. Pokud máte jinou verzi MSDN než Januar 2004, je potřeba upravit odkaz ve volání "SetCollection". Upozorňuji na nutnost dát proměnnou oHelp jako globální.