/*------------------------------------------------
   STRLIB.C -- Library module for STRPROG program
               (c) Charles Petzold, 1998
  ------------------------------------------------*/#include <windows.h>
#include <wchar.h>       // for wide-character string functions
#include "strlib.h"     // shared memory section (requires /SECTION:shared,RWS in link options)#pragma data_seg ("shared")
int   iTotal = 0 ;
WCHAR szStrings [MAX_STRINGS][MAX_LENGTH + 1] = { '\0' } ;
#pragma data_seg ()#pragma comment(linker,"/SECTION:shared,RWS")int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
     return TRUE ;
}EXPORT BOOL CALLBACK AddStringA (PCSTR pStringIn)
{
     BOOL  bReturn ;
     int   iLength ;
     PWSTR pWideStr ;          // Convert string to Unicode and call AddStringW     iLength = MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, NULL, 0) ;
     pWideStr = malloc (iLength) ;
     MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, pWideStr, iLength) ;
     bReturn = AddStringW (pWideStr) ;
     free (pWideStr) ;     return bReturn ;
}EXPORT BOOL CALLBACK AddStringW (PCWSTR pStringIn)
{
     PWSTR pString ;
     int   i, iLength ;
     
     if (iTotal == MAX_STRINGS - 1)
          return FALSE ;
     
     if ((iLength = wcslen (pStringIn)) == 0)
          return FALSE ;          // Allocate memory for storing string, copy it, convert to upper case     pString = malloc (sizeof (WCHAR) * (1 + iLength)) ;
     wcscpy (pString, pStringIn) ;
     _wcsupr (pString) ;          // Alphabetize the strings
     
     for (i = iTotal ; i > 0 ; i--)
     {
          if (wcscmp (pString, szStrings[i - 1]) >= 0)
               break ;
          
          wcscpy (szStrings[i], szStrings[i - 1]) ;
     }
     wcscpy (szStrings[i], pString) ;
     iTotal++ ;     free (pString) ;
     return TRUE ;
}EXPORT BOOL CALLBACK DeleteStringA (PCSTR pStringIn)
{
     BOOL  bReturn ;
     int   iLength ;
     PWSTR pWideStr ;          // Convert string to Unicode and call DeleteStringW     iLength = MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, NULL, 0) ;
     pWideStr = malloc (iLength) ;
     MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, pWideStr, iLength) ;
     bReturn = DeleteStringW (pWideStr) ;
     free (pWideStr) ;     return bReturn ;
}EXPORT BOOL CALLBACK DeleteStringW (PCWSTR pStringIn)
{
     int i, j ;
     
     if (0 == wcslen (pStringIn))
          return FALSE ;
     
     for (i = 0 ; i < iTotal ; i++)
     {
          if (_wcsicmp (szStrings[i], pStringIn) == 0)
               break ;
     }
          // If given string not in list, return without taking action
     
     if (i == iTotal)
          return FALSE ;
     
          // Else adjust list downward
     
     for (j = i ; j < iTotal ; j++)
          wcscpy (szStrings[j], szStrings[j + 1]) ;
     
     szStrings[iTotal--][0] = '\0' ;
     return TRUE ;
}EXPORT int CALLBACK GetStringsA (GETSTRCB pfnGetStrCallBack, PVOID pParam)
{
     BOOL bReturn ;
     int  i, iLength ;
     PSTR pAnsiStr ;     for (i = 0 ; i < iTotal ; i++)
     {
               // Convert string from Unicode          iLength = WideCharToMultiByte (CP_ACP, 0, szStrings[i], -1, NULL, 0,
                                         NULL, NULL) ;
          pAnsiStr = malloc (iLength) ;
          WideCharToMultiByte (CP_ACP, 0, szStrings[i], -1, pAnsiStr, iLength,
                                          NULL, NULL) ;               // Call callback function          bReturn = pfnGetStrCallBack (pAnsiStr, pParam) ;
          
          if (bReturn == FALSE)
               return i + 1 ;          free (pAnsiStr) ;
     }
     return iTotal ;
}EXPORT int CALLBACK GetStringsW (GETSTRCB pfnGetStrCallBack, PVOID pParam)
{
     BOOL bReturn ;
     int  i ;
     
     for (i = 0 ; i < iTotal ; i++)
     {
          bReturn = pfnGetStrCallBack (szStrings[i], pParam) ;
          
          if (bReturn == FALSE)
               return i + 1 ;
     }
     return iTotal ;
}

解决方案 »

  1.   

    /*----------------------
       STRLIB.H header file
      ----------------------*/#ifdef __cplusplus
    #define EXPORT extern "C" __declspec (dllexport)
    #else
    #define EXPORT __declspec (dllexport)
    #endif     // The maximum number of strings STRLIB will store and their lengths#define MAX_STRINGS 256
    #define MAX_LENGTH  64     // The callback function type definition uses generic stringstypedef BOOL (CALLBACK * GETSTRCB) (PCTSTR, PVOID) ;     // Each function has ANSI and Unicode versionsEXPORT BOOL CALLBACK AddStringA (PCSTR) ;
    EXPORT BOOL CALLBACK AddStringW (PCWSTR) ;EXPORT BOOL CALLBACK DeleteStringA (PCSTR) ;
    EXPORT BOOL CALLBACK DeleteStringW (PCWSTR) ;EXPORT int CALLBACK GetStringsA (GETSTRCB, PVOID) ;
    EXPORT int CALLBACK GetStringsW (GETSTRCB, PVOID) ;     // Use the correct version depending on the UNICODE identifier#ifdef UNICODE
    #define AddString    AddStringW
    #define DeleteString DeleteStringW
    #define GetStrings   GetStringsW
    #else
    #define AddString    AddStringA
    #define DeleteString DeleteStringA
    #define GetStrings   GetStringsA
    #endif
      

  2.   

    /*--------------------------------------------------------
       STRPROG.C -- Program using STRLIB dynamic-link library
                    (c) Charles Petzold, 1998
      --------------------------------------------------------*/#include <windows.h>
    #include "strlib.h"
    #include "resource.h"typedef struct
    {
         HDC hdc ;
         int xText ;
         int yText ;
         int xStart ;
         int yStart ;
         int xIncr ;
         int yIncr ;
         int xMax ;
         int yMax ;
    }
    CBPARAM ;LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;TCHAR szAppName [] = TEXT ("StrProg") ;
    TCHAR szString [MAX_LENGTH + 1] ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
         HWND     hwnd ;
         MSG      msg ;
         WNDCLASS wndclass ;
         
         wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
         wndclass.lpfnWndProc   = WndProc ;
         wndclass.cbClsExtra    = 0 ;
         wndclass.cbWndExtra    = 0 ;
         wndclass.hInstance     = hInstance ;
         wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
         wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
         wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
         wndclass.lpszMenuName  = szAppName ;
         wndclass.lpszClassName = szAppName ;
         
         if (!RegisterClass (&wndclass))
         {
              MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                          szAppName, MB_ICONERROR) ;
              return 0 ;
         }     hwnd = CreateWindow (szAppName, TEXT ("DLL Demonstration Program"),
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              NULL, NULL, hInstance, NULL) ;
         
         ShowWindow (hwnd, iCmdShow) ;
         UpdateWindow (hwnd) ;
         
         while (GetMessage (&msg, NULL, 0, 0))
         {
              TranslateMessage (&msg) ;
              DispatchMessage (&msg) ;
         }
         return msg.wParam ;
    }BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
         switch (message)
         {
         case WM_INITDIALOG:
              SendDlgItemMessage (hDlg, IDC_STRING, EM_LIMITTEXT, MAX_LENGTH, 0) ;
              return TRUE ;
              
         case WM_COMMAND:
              switch (wParam)
              {
              case IDOK:
                   GetDlgItemText (hDlg, IDC_STRING, szString, MAX_LENGTH) ;
                   EndDialog (hDlg, TRUE) ;
                   return TRUE ;
                   
              case IDCANCEL:
                   EndDialog (hDlg, FALSE) ;
                   return TRUE ;
              }
         }
         return FALSE ;
    }BOOL CALLBACK GetStrCallBack (PTSTR pString, CBPARAM * pcbp)
    {
         TextOut (pcbp->hdc, pcbp->xText, pcbp->yText,
                  pString, lstrlen (pString)) ;
         
         if ((pcbp->yText += pcbp->yIncr) > pcbp->yMax)
         {
              pcbp->yText = pcbp->yStart ;
              if ((pcbp->xText += pcbp->xIncr) > pcbp->xMax)
                   return FALSE ;
         }
         return TRUE ;
    }LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
         static HINSTANCE  hInst ;
         static int        cxChar, cyChar, cxClient, cyClient ;
         static UINT       iDataChangeMsg ;
         CBPARAM           cbparam ;
         HDC               hdc ;
         PAINTSTRUCT       ps ;
         TEXTMETRIC        tm ;
         
         switch (message)
         {
         case WM_CREATE:
              hInst = ((LPCREATESTRUCT) lParam)->hInstance ;
              hdc   = GetDC (hwnd) ;
              GetTextMetrics (hdc, &tm) ;
              cxChar = (int) tm.tmAveCharWidth ;
              cyChar = (int) (tm.tmHeight + tm.tmExternalLeading) ;
              ReleaseDC (hwnd, hdc) ;               // Register message for notifying instances of data changes          iDataChangeMsg = RegisterWindowMessage (TEXT ("StrProgDataChange")) ;
              return 0 ;
              
         case WM_COMMAND:
              switch (wParam)
              {
              case IDM_ENTER:
                   if (DialogBox (hInst, TEXT ("EnterDlg"), hwnd, &DlgProc))
                   {
                        if (AddString (szString))
                             PostMessage (HWND_BROADCAST, iDataChangeMsg, 0, 0) ;
                        else
                             MessageBeep (0) ;
                   }
                   break ;
                   
              case IDM_DELETE:
                   if (DialogBox (hInst, TEXT ("DeleteDlg"), hwnd, &DlgProc))
                   {
                        if (DeleteString (szString))
                             PostMessage (HWND_BROADCAST, iDataChangeMsg, 0, 0) ;
                        else
                             MessageBeep (0) ;
                   }
                   break ;
              }
              return 0 ;
              
         case WM_SIZE:
              cxClient = (int) LOWORD (lParam) ;
              cyClient = (int) HIWORD (lParam) ;
              return 0 ;
                   
         case WM_PAINT:
              hdc = BeginPaint (hwnd, &ps) ;
                   
              cbparam.hdc   = hdc ;
              cbparam.xText = cbparam.xStart = cxChar ;
              cbparam.yText = cbparam.yStart = cyChar ;
              cbparam.xIncr = cxChar * MAX_LENGTH ;
              cbparam.yIncr = cyChar ;
              cbparam.xMax  = cbparam.xIncr * (1 + cxClient / cbparam.xIncr) ;
              cbparam.yMax  = cyChar * (cyClient / cyChar - 1) ;
                   
              GetStrings ((GETSTRCB) GetStrCallBack, (PVOID) &cbparam) ;
                  
              EndPaint (hwnd, &ps) ;
              return 0 ;
                   
         case WM_DESTROY:
              PostQuitMessage (0) ;
              return 0 ;     default:
              if (message == iDataChangeMsg)
                   InvalidateRect (hwnd, NULL, TRUE) ;
              break ;
         }
         return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
      

  3.   

    //Microsoft Developer Studio generated resource script.
    //
    #include "resource.h"#define APSTUDIO_READONLY_SYMBOLS
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"/////////////////////////////////////////////////////////////////////////////
    #undef APSTUDIO_READONLY_SYMBOLS/////////////////////////////////////////////////////////////////////////////
    // English (U.S.) resources#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    #ifdef _WIN32
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    #endif //_WIN32#ifdef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // TEXTINCLUDE
    //1 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "resource.h\0"
    END2 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END3 TEXTINCLUDE DISCARDABLE 
    BEGIN
        "\r\n"
        "\0"
    END#endif    // APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Dialog
    //ENTERDLG DIALOG DISCARDABLE  20, 20, 186, 47
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
    CAPTION "Enter"
    FONT 8, "MS Sans Serif"
    BEGIN
        LTEXT           "&Enter:",IDC_STATIC,7,7,26,9
        EDITTEXT        IDC_STRING,31,7,148,12,ES_AUTOHSCROLL
        DEFPUSHBUTTON   "OK",IDOK,32,26,50,14
        PUSHBUTTON      "Cancel",IDCANCEL,104,26,50,14
    ENDDELETEDLG DIALOG DISCARDABLE  20, 20, 186, 47
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
    CAPTION "Delete"
    FONT 8, "MS Sans Serif"
    BEGIN
        LTEXT           "&Delete:",IDC_STATIC,7,7,26,9
        EDITTEXT        IDC_STRING,31,7,148,12,ES_AUTOHSCROLL
        DEFPUSHBUTTON   "OK",IDOK,32,26,50,14
        PUSHBUTTON      "Cancel",IDCANCEL,104,26,50,14
    END
    /////////////////////////////////////////////////////////////////////////////
    //
    // Menu
    //STRPROG MENU DISCARDABLE 
    BEGIN
        MENUITEM "&Enter!",                     IDM_ENTER
        MENUITEM "&Delete!",                    IDM_DELETE
    END
    /////////////////////////////////////////////////////////////////////////////
    //
    // DESIGNINFO
    //#ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO DISCARDABLE 
    BEGIN
        "ENTERDLG", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 179
            TOPMARGIN, 7
            BOTTOMMARGIN, 40
        END    "DELETEDLG", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 179
            TOPMARGIN, 7
            BOTTOMMARGIN, 40
        END
    END
    #endif    // APSTUDIO_INVOKED#endif    // English (U.S.) resources
    /////////////////////////////////////////////////////////////////////////////#ifndef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    /////////////////////////////////////////////////////////////////////////////
    #endif    // not APSTUDIO_INVOKED
      

  4.   

    首先不要在C++里使用malloc 和free !
    AddStringA 和DeleteStringA有错误!iLength = MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, NULL, 0) ;
    iLength 返回的是宽字符个数,分配内存时应使用malloc(iLength * sizeof(WCHAR)).
    最好使用new来分配。