Esempio n. 1
0
int WINAPI createCfgDlg()
{
  g_is_back=0;
  g_is_cancel=0;

  HWND mainwnd = hMainWindow;
  if (!mainwnd)
  {
    popstring(NULL);
    pushstring("error finding mainwnd");
    return 1; // cannot be used in silent mode unfortunately.
  }

  if (!g_stacktop || !*g_stacktop || !(pszFilename = (*g_stacktop)->text) || !pszFilename[0] || !ReadSettings())
  {
    popstring(NULL);
    pushstring("error finding config");
    return 1;
  }

  HWND childwnd=GetDlgItem(mainwnd,nRectId);
  if (!childwnd)
  {
    popstring(NULL);
    pushstring("error finding childwnd");
    return 1;
  }

  hCancelButton = GetDlgItem(mainwnd,IDCANCEL);
  hNextButton = GetDlgItem(mainwnd,IDOK);
  hBackButton = GetDlgItem(mainwnd,3);

  mySetWindowText(hCancelButton,pszCancelButtonText);
  mySetWindowText(hNextButton,pszNextButtonText);
  mySetWindowText(hBackButton,pszBackButtonText);

  if (bBackEnabled!=-1) EnableWindow(hBackButton,bBackEnabled);
  if (bCancelEnabled!=-1) EnableWindow(hCancelButton,bCancelEnabled);
  if (bCancelShow!=-1) old_cancel_visible=ShowWindow(hCancelButton,bCancelShow?SW_SHOWNA:SW_HIDE);

  HFONT hFont = (HFONT)mySendMessage(mainwnd, WM_GETFONT, 0, 0);

  RECT dialog_r;
  int mainWndWidth, mainWndHeight;
  hConfigWindow=CreateDialog(m_hInstance,MAKEINTRESOURCE(IDD_DIALOG1),mainwnd,cfgDlgProc);
  if (hConfigWindow)
  {
    GetWindowRect(childwnd,&dialog_r);
    MapWindowPoints(0, mainwnd, (LPPOINT) &dialog_r, 2);
    mainWndWidth = dialog_r.right - dialog_r.left;
    mainWndHeight = dialog_r.bottom - dialog_r.top;
    SetWindowPos(
      hConfigWindow,
      0,
      dialog_r.left,
      dialog_r.top,
      mainWndWidth,
      mainWndHeight,
      SWP_NOZORDER|SWP_NOACTIVATE
    );
    // Sets the font of IO window to be the same as the main window
    mySendMessage(hConfigWindow, WM_SETFONT, (WPARAM)hFont, TRUE);
  }
  else
  {
    popstring(NULL);
    pushstring("error creating dialog");
    return 1;
  }

  // Init dialog unit conversion

  HDC memDC = CreateCompatibleDC(GetDC(hConfigWindow));
  SelectObject(memDC, hFont);

  TEXTMETRIC tm;
  GetTextMetrics(memDC, &tm);
  int baseUnitY = tm.tmHeight;

  SIZE size;
  GetTextExtentPoint32(memDC,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &size);
  int baseUnitX = (size.cx / 26 + 1) / 2;

  DeleteDC(memDC);

  BOOL fFocused = FALSE;

#define DEFAULT_STYLES (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS)

  for (int nIdx = 0; nIdx < nNumFields; nIdx++) {
    static struct {
      char* pszClass;
      DWORD dwStyle;
      DWORD dwRTLStyle;
      DWORD dwExStyle;
      DWORD dwRTLExStyle;
    } ClassTable[] = {
      { "STATIC",       // FIELD_LABEL
        DEFAULT_STYLES,
        DEFAULT_STYLES | SS_RIGHT,
        WS_EX_TRANSPARENT,
        WS_EX_TRANSPARENT | WS_EX_RTLREADING },
      { "STATIC",       // FIELD_ICON
        DEFAULT_STYLES | SS_ICON,
        DEFAULT_STYLES | SS_ICON,
        0,
        WS_EX_RTLREADING },
      { "STATIC",       // FIELD_BITMAP
        DEFAULT_STYLES | SS_BITMAP | SS_CENTERIMAGE,
        DEFAULT_STYLES | SS_BITMAP | SS_CENTERIMAGE,
        0,
        WS_EX_RTLREADING },
      { "BUTTON",       // FIELD_BROWSEBUTTON
        DEFAULT_STYLES | WS_TABSTOP,
        DEFAULT_STYLES | WS_TABSTOP,
        0,
        WS_EX_RTLREADING },
      { "BUTTON",       // FIELD_CHECKBOX
        DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTOCHECKBOX | BS_MULTILINE,
        DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTOCHECKBOX | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT,
        0,
        WS_EX_RTLREADING },
      { "BUTTON",       // FIELD_RADIOBUTTON
        DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTORADIOBUTTON | BS_MULTILINE,
        DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTORADIOBUTTON | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT,
        0,
        WS_EX_RTLREADING },
      { "EDIT",         // FIELD_TEXT
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL,
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RTLREADING },
      { "EDIT",         // FIELD_FILEREQUEST
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL,
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RTLREADING },
      { "EDIT",         // FIELD_DIRREQUEST
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL,
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RTLREADING },
      { "COMBOBOX",     // FIELD_COMBOBOX
        DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | CBS_AUTOHSCROLL | CBS_HASSTRINGS,
        DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | CBS_AUTOHSCROLL | CBS_HASSTRINGS,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RIGHT | WS_EX_RTLREADING },
      { "LISTBOX",      // FIELD_LISTBOX
        DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT,
        DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RIGHT | WS_EX_RTLREADING },
      { "BUTTON",       // FIELD_GROUPBOX
        DEFAULT_STYLES | BS_GROUPBOX,
        DEFAULT_STYLES | BS_GROUPBOX | BS_RIGHT,
        WS_EX_TRANSPARENT,
        WS_EX_TRANSPARENT | WS_EX_RTLREADING },
      { "BUTTON",       // FIELD_LINK
        DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW,
        DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW | BS_RIGHT,
        0,
        WS_EX_RTLREADING },
      { "BUTTON",       // FIELD_BUTTON
        DEFAULT_STYLES | WS_TABSTOP,
        DEFAULT_STYLES | WS_TABSTOP,
        0,
        WS_EX_RTLREADING }
    };

    FieldType *pField = pFields + nIdx;

#undef DEFAULT_STYLES

    if (pField->nType < 1 || pField->nType > (sizeof(ClassTable) / sizeof(ClassTable[0])))
      continue;

    DWORD dwStyle, dwExStyle;
    if (bRTL) {
      dwStyle = ClassTable[pField->nType - 1].dwRTLStyle;
      dwExStyle = ClassTable[pField->nType - 1].dwRTLExStyle;
    }
    else {
      dwStyle = ClassTable[pField->nType - 1].dwStyle;
      dwExStyle = ClassTable[pField->nType - 1].dwExStyle;
    }

    // Convert from dialog units

    RECT rect;

    rect.left = MulDiv(pField->rect.left, baseUnitX, 4);
    rect.right = MulDiv(pField->rect.right, baseUnitX, 4);
    rect.top = MulDiv(pField->rect.top, baseUnitY, 8);
    rect.bottom = MulDiv(pField->rect.bottom, baseUnitY, 8);

    if (pField->rect.left < 0)
      rect.left += mainWndWidth;
    if (pField->rect.right < 0)
      rect.right += mainWndWidth;
    if (pField->rect.top < 0)
      rect.top += mainWndHeight;
    if (pField->rect.bottom < 0)
      rect.bottom += mainWndHeight;

    if (bRTL) {
      int right = rect.right;
      rect.right = mainWndWidth - rect.left;
      rect.left = mainWndWidth - right;
    }

    char *title = pField->pszText;
    switch (pField->nType) {
      case FIELD_ICON:
      case FIELD_BITMAP:
        title = NULL; // otherwise it is treated as the name of a resource
        break;
      case FIELD_CHECKBOX:
      case FIELD_RADIOBUTTON:
        dwStyle ^= pField->nFlags & BS_LEFTTEXT;
        break;
      case FIELD_TEXT:
      case FIELD_FILEREQUEST:
      case FIELD_DIRREQUEST:
        if (pField->nFlags & FLAG_PASSWORD)
          dwStyle |= ES_PASSWORD;
        if (pField->nFlags & FLAG_ONLYNUMBERS)
          dwStyle |= ES_NUMBER;
        if (pField->nFlags & FLAG_WANTRETURN)
          dwStyle |= ES_WANTRETURN;
        if (pField->nFlags & FLAG_READONLY)
          dwStyle |= ES_READONLY;
        title = pField->pszState;
        if (pField->nFlags & FLAG_MULTILINE)
        {
          dwStyle |= ES_MULTILINE | ES_AUTOVSCROLL;
          // Enable word-wrap unless we have a horizontal scroll bar
          // or it has been explicitly disallowed
          if (!(pField->nFlags & (WS_HSCROLL | FLAG_NOWORDWRAP)))
            dwStyle &= ~ES_AUTOHSCROLL;
          ConvertNewLines(pField->pszState);
          // If multiline-readonly then hold the text back until after the
          // initial focus has been set. This is so the text is not initially
          // selected - useful for License Page look-a-likes.
          if (pField->nFlags & FLAG_READONLY)
            title = NULL;
        }
        break;
      case FIELD_COMBOBOX:
        dwStyle |= (pField->nFlags & FLAG_DROPLIST) ? CBS_DROPDOWNLIST : CBS_DROPDOWN;
        title = pField->pszState;
        break;
      case FIELD_LISTBOX:
        dwStyle |= pField->nFlags & (LBS_NOTIFY | LBS_MULTIPLESEL | LBS_EXTENDEDSEL);
        break;
    }

    dwStyle |= pField->nFlags & (WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_DISABLED);
    if (pField->nFlags & WS_TABSTOP) dwStyle &= ~WS_TABSTOP;

    HWND hwCtrl = pField->hwnd = CreateWindowEx(
      dwExStyle,
      ClassTable[pField->nType - 1].pszClass,
      title,
      dwStyle,
      rect.left,
      rect.top,
      rect.right - rect.left,
      rect.bottom - rect.top,
      hConfigWindow,
      (HMENU)pField->nControlID,
      m_hInstance,
      NULL
    );

    if (hwCtrl) {
      // Sets the font of IO window to be the same as the main window
      mySendMessage(hwCtrl, WM_SETFONT, (WPARAM)hFont, TRUE);
      // make sure we created the window, then set additional attributes
      switch (pField->nType) {
        case FIELD_TEXT:
        case FIELD_FILEREQUEST:
        case FIELD_DIRREQUEST:
          mySendMessage(hwCtrl, EM_LIMITTEXT, (WPARAM)pField->nMaxLength, (LPARAM)0);
          break;

        case FIELD_CHECKBOX:
        case FIELD_RADIOBUTTON:
          if (pField->pszState[0] == '1')
            mySendMessage(hwCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
          break;

        case FIELD_COMBOBOX:
        case FIELD_LISTBOX:
          // if this is a listbox or combobox, we need to add the list items.
          if (pField->pszListItems) {
            UINT nAddMsg, nFindMsg, nSetSelMsg;
            if (pField->nType == FIELD_COMBOBOX) {
              nAddMsg = CB_ADDSTRING;
              nFindMsg = CB_FINDSTRINGEXACT;
              nSetSelMsg = CB_SETCURSEL;
            }
            else {
              nAddMsg = LB_ADDSTRING;
              nFindMsg = LB_FINDSTRINGEXACT;
              nSetSelMsg = LB_SETCURSEL;
            }
            char *pszStart, *pszEnd, *pszList;
            pszStart = pszEnd = pszList = STRDUP(pField->pszListItems);
            while ((*pszEnd) && (*pszStart)) {
              if (*pszEnd == '|') {
                *pszEnd = '\0';
                if (pszEnd > pszStart) {
                  mySendMessage(hwCtrl, nAddMsg, 0, (LPARAM)pszStart);
                }
                // jump to the next item, skip any redundant | characters
                do { pszEnd++; } while (*pszEnd == '|');
                pszStart = pszEnd;
              }
              pszEnd++;
            }
            FREE(pszList);
            if (pField->pszState) {
              if (pField->nFlags & (LBS_MULTIPLESEL|LBS_EXTENDEDSEL) && nFindMsg == LB_FINDSTRINGEXACT) {
                mySendMessage(hwCtrl, LB_SETSEL, FALSE, -1);
                pszStart = pszEnd = pField->pszState;
                while (*pszStart) {
                  char cLast = *pszEnd;
                  if (*pszEnd == '|') *pszEnd = '\0';
                  if (!*pszEnd) {
                    if (pszEnd > pszStart) {
                      int nItem = mySendMessage(hwCtrl, nFindMsg, -1, (LPARAM)pszStart);
                      if (nItem != CB_ERR) { // CB_ERR == LB_ERR == -1
                        mySendMessage(hwCtrl, LB_SETSEL, TRUE, nItem);
                      }
                    }
                    if (cLast) {
                      do {
                        pszEnd++;
                      } while (*pszEnd == '|');
                    }
                    pszStart = pszEnd;
                  }
                  pszEnd++;
                }
              }
              else {
                int nItem = mySendMessage(hwCtrl, nFindMsg, -1, (LPARAM)pField->pszState);
                if (nItem != CB_ERR) { // CB_ERR == LB_ERR == -1
                  mySendMessage(hwCtrl, nSetSelMsg, nItem, 0);
                }
              }
            }
          }
          break;

        case FIELD_ICON:
        case FIELD_BITMAP:
        {
          WPARAM nImageType = pField->nType == FIELD_BITMAP ? IMAGE_BITMAP : IMAGE_ICON;
          LPARAM nImage = 0;
          if (pField->pszText) {
            pField->hImage = LoadImage(
              m_hInstance,
              pField->pszText,
              nImageType,
              (pField->nFlags & FLAG_RESIZETOFIT)
                ? (rect.right - rect.left)
                : 0,
              (pField->nFlags & FLAG_RESIZETOFIT)
                ? (rect.bottom - rect.top)
                : 0,
              LR_LOADFROMFILE
            );
            nImage = (LPARAM)pField->hImage;
          }
          else
            nImage = (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(103));
          mySendMessage(
            hwCtrl,
            STM_SETIMAGE,
            nImageType,
            nImage
          );
          break;
        }

#ifdef IO_ENABLE_LINK
        case FIELD_LINK:
          pField->nParentIdx = SetWindowLong(hwCtrl, GWL_WNDPROC, (long)StaticLINKWindowProc);
          break;
#endif
      }

      // Set initial focus to the first appropriate field
      if (!fFocused && (dwStyle & (WS_TABSTOP | WS_DISABLED)) == WS_TABSTOP) {
        fFocused = TRUE;
        mySetFocus(hwCtrl);
      }

      // If multiline-readonly then hold the text back until after the
      // initial focus has been set. This is so the text is not initially
      // selected - useful for License Page look-a-likes.
      if ((pField->nFlags & (FLAG_MULTILINE | FLAG_READONLY)) == (FLAG_MULTILINE | FLAG_READONLY))
        mySetWindowText(hwCtrl, pField->pszState);
    }
  }

  if (!fFocused)
    mySetFocus(hNextButton);

  mySetWindowText(mainwnd,pszTitle);
  pFilenameStackEntry = *g_stacktop;
  *g_stacktop = (*g_stacktop)->next;
  static char tmp[32];
  wsprintf(tmp,"%d",hConfigWindow);
  pushstring(tmp);
  return 0;
}
Esempio n. 2
0
LRESULT WINAPI WMCommandProc(HWND hWnd, UINT id, HWND hwndCtl, UINT codeNotify) {
  switch (codeNotify) {
    case BN_CLICKED:    // The user pressed a button
    case LBN_SELCHANGE: // The user changed the selection in a ListBox control
//  case CBN_SELCHANGE: // The user changed the selection in a DropList control (same value as LBN_SELCHANGE)
    {
      char szBrowsePath[MAX_PATH];
      int nIdx = FindControlIdx(id);
      if (nIdx < 0)
        break;
      if (pFields[nIdx].nType == FIELD_BROWSEBUTTON)
        --nIdx;
      FieldType *pField = pFields + nIdx;
      switch (pField->nType) {
        case FIELD_FILEREQUEST: {
          OPENFILENAME ofn={0,};

          ofn.lStructSize = sizeof(ofn);
          ofn.hwndOwner = hConfigWindow;
          ofn.lpstrFilter = pField->pszFilter;
          ofn.lpstrFile = szBrowsePath;
          ofn.nMaxFile  = sizeof(szBrowsePath);
          ofn.Flags = pField->nFlags & (OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_CREATEPROMPT | OFN_EXPLORER);

          GetWindowText(pField->hwnd, szBrowsePath, sizeof(szBrowsePath));

        tryagain:
          if ((pField->nFlags & FLAG_SAVEAS) ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn)) {
            mySetWindowText(pField->hwnd, szBrowsePath);
            break;
          }
          else if (szBrowsePath[0] && CommDlgExtendedError() == FNERR_INVALIDFILENAME) {
            szBrowsePath[0] = '\0';
            goto tryagain;
          }

          break;
        }

        case FIELD_DIRREQUEST: {
          BROWSEINFO bi;

          bi.hwndOwner = hConfigWindow;
          bi.pidlRoot = NULL;
          bi.pszDisplayName = szBrowsePath;
          bi.lpszTitle = pField->pszText;
#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#endif
          bi.ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
          bi.lpfn = BrowseCallbackProc;
          bi.lParam = nIdx;
          bi.iImage = 0;

          if (pField->pszRoot) {
            LPSHELLFOLDER sf;
            ULONG eaten;
            LPITEMIDLIST root;
            int ccRoot = (lstrlen(pField->pszRoot) * 2) + 2;
            LPWSTR pwszRoot = (LPWSTR) MALLOC(ccRoot);
            MultiByteToWideChar(CP_ACP, 0, pField->pszRoot, -1, pwszRoot, ccRoot);
            SHGetDesktopFolder(&sf);
            sf->ParseDisplayName(hConfigWindow, NULL, pwszRoot, &eaten, &root, NULL);
            bi.pidlRoot = root;
            sf->Release();
            FREE(pwszRoot);
          }
//          CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
          LPITEMIDLIST pResult = SHBrowseForFolder(&bi);
          if (!pResult)
            break;

          if (SHGetPathFromIDList(pResult, szBrowsePath)) {
            mySetWindowText(pField->hwnd, szBrowsePath);
          }

          LPMALLOC pMalloc;
          if (!SHGetMalloc(&pMalloc)) {
            pMalloc->Free(pResult);
          }

          break;
        }

        case FIELD_LINK:
        case FIELD_BUTTON:
          // Allow the state to be empty - this might be useful in conjunction
          // with the NOTIFY flag
          if (*pField->pszState)
            ShellExecute(hMainWindow, NULL, pField->pszState, NULL, NULL, SW_SHOWDEFAULT);
          break;
      }

      if (pField->nFlags & LBS_NOTIFY) {
        // Remember which control was activated then pretend the user clicked Next
        g_NotifyField = nIdx + 1;
        // the next button must be enabled or nsis will ignore WM_COMMAND
        BOOL bWasDisabled = EnableWindow(hNextButton, TRUE);
        FORWARD_WM_COMMAND(hMainWindow, IDOK, hNextButton, BN_CLICKED, mySendMessage);
        if (bWasDisabled)
          EnableWindow(hNextButton, FALSE);
      }
    }
    break;
  }
  return 0;
}
Esempio n. 3
0
LRESULT WINAPI WMCommandProc(HWND hWnd, UINT id, HWND hwndCtl, UINT codeNotify) {
  int nIdx = FindControlIdx(id);
  // Ignore if the dialog is in the process of being created
  if (g_done || nIdx < 0)
    return 0;

  switch (pFields[nIdx].nType)
  {
    case FIELD_BROWSEBUTTON:
      --nIdx;
    case FIELD_LINK:
    case FIELD_BUTTON:
    case FIELD_CHECKBOX:
    case FIELD_RADIOBUTTON:
      if (codeNotify != BN_CLICKED)
        return 0;
      break;
    case FIELD_COMBOBOX:
    case FIELD_LISTBOX:
      if (codeNotify != LBN_SELCHANGE) // LBN_SELCHANGE == CBN_SELCHANGE
        return 0;
      break;
    default:
      return 0;
  }

  FieldType *pField = pFields + nIdx;

  char szBrowsePath[MAX_PATH];

  switch (pField->nType) {
    case FIELD_FILEREQUEST: {
      OPENFILENAME ofn={0,};

      ofn.lStructSize = sizeof(ofn);
      ofn.hwndOwner = hConfigWindow;
      ofn.lpstrFilter = pField->pszFilter;
      ofn.lpstrFile = szBrowsePath;
      ofn.nMaxFile  = sizeof(szBrowsePath);
      ofn.Flags = pField->nFlags & (OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_CREATEPROMPT | OFN_EXPLORER);

      GetWindowText(pField->hwnd, szBrowsePath, sizeof(szBrowsePath));

    tryagain:
      GetCurrentDirectory(BUFFER_SIZE, szResult); // save working dir
      if ((pField->nFlags & FLAG_SAVEAS) ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn)) {
        mySetWindowText(pField->hwnd, szBrowsePath);
        SetCurrentDirectory(szResult); // restore working dir
                                       // OFN_NOCHANGEDIR doesn't always work (see MSDN)
        break;
      }
      else if (szBrowsePath[0] && CommDlgExtendedError() == FNERR_INVALIDFILENAME) {
        szBrowsePath[0] = '\0';
        goto tryagain;
      }

      break;
    }

    case FIELD_DIRREQUEST: {
      BROWSEINFO bi;

      bi.hwndOwner = hConfigWindow;
      bi.pidlRoot = NULL;
      bi.pszDisplayName = szBrowsePath;
      bi.lpszTitle = pField->pszText;
#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#endif
      bi.ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
      bi.lpfn = BrowseCallbackProc;
      bi.lParam = nIdx;
      bi.iImage = 0;

      if (pField->pszRoot) {
        LPSHELLFOLDER sf;
        ULONG eaten;
        LPITEMIDLIST root;
        int ccRoot = (lstrlen(pField->pszRoot) * 2) + 2;
        LPWSTR pwszRoot = (LPWSTR) MALLOC(ccRoot);
        MultiByteToWideChar(CP_ACP, 0, pField->pszRoot, -1, pwszRoot, ccRoot);
        SHGetDesktopFolder(&sf);
        sf->ParseDisplayName(hConfigWindow, NULL, pwszRoot, &eaten, &root, NULL);
        bi.pidlRoot = root;
        sf->Release();
        FREE(pwszRoot);
      }
      //CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
      LPITEMIDLIST pResult = SHBrowseForFolder(&bi);
      if (!pResult)
        break;

      if (SHGetPathFromIDList(pResult, szBrowsePath)) {
        mySetWindowText(pField->hwnd, szBrowsePath);
      }

      CoTaskMemFree(pResult);

      break;
    }

    case FIELD_LINK:
    case FIELD_BUTTON:
      // Allow the state to be empty - this might be useful in conjunction
      // with the NOTIFY flag
      if (*pField->pszState)
        ShellExecute(hMainWindow, NULL, pField->pszState, NULL, NULL, SW_SHOWDEFAULT);
      break;
  }

  if (pField->nFlags & LBS_NOTIFY) {
    // Remember which control was activated then pretend the user clicked Next
    g_NotifyField = nIdx + 1;
    mySendMessage(hMainWindow, WM_NOTIFY_OUTER_NEXT, 1, 0);
  }

  return 0;
}
Esempio n. 4
0
int WINAPI createCfgDlg()
{
  g_is_back=0;
  g_is_cancel=0;

  HWND mainwnd = hMainWindow;
  if (!mainwnd)
  {
    popstring(NULL);
    pushstring("error finding mainwnd");
    return 1; // cannot be used in silent mode unfortunately.
  }

  if (!g_stacktop || !*g_stacktop || !(pszFilename = (*g_stacktop)->text) || !pszFilename[0] || !ReadSettings())
  {
    popstring(NULL);
    pushstring("error finding config");
    return 1;
  }

  HWND childwnd=GetDlgItem(mainwnd,nRectId);
  if (!childwnd)
  {
    popstring(NULL);
    pushstring("error finding childwnd");
    return 1;
  }

  hCancelButton = GetDlgItem(mainwnd,IDCANCEL);
  hNextButton = GetDlgItem(mainwnd,IDOK);
  hBackButton = GetDlgItem(mainwnd,3);

  mySetWindowText(hCancelButton,pszCancelButtonText);
  mySetWindowText(hNextButton,pszNextButtonText);
  mySetWindowText(hBackButton,pszBackButtonText);

  if (bBackEnabled!=-1) EnableWindow(hBackButton,bBackEnabled);
  if (bCancelEnabled!=-1) EnableWindow(hCancelButton,bCancelEnabled);
  if (bCancelShow!=-1) old_cancel_visible=ShowWindow(hCancelButton,bCancelShow?SW_SHOWNA:SW_HIDE);

  HFONT hFont = (HFONT)mySendMessage(mainwnd, WM_GETFONT, 0, 0);

  // Prevent WM_COMMANDs from being processed while we are building
  g_done = 1;

  int mainWndWidth, mainWndHeight;
  hConfigWindow=CreateDialog(m_hInstance,MAKEINTRESOURCE(IDD_DIALOG1),mainwnd,cfgDlgProc);
  if (hConfigWindow)
  {
    RECT dialog_r;
    GetWindowRect(childwnd,&dialog_r);
    MapWindowPoints(0, mainwnd, (LPPOINT) &dialog_r, 2);
    mainWndWidth = dialog_r.right - dialog_r.left;
    mainWndHeight = dialog_r.bottom - dialog_r.top;
    SetWindowPos(
      hConfigWindow,
      0,
      dialog_r.left,
      dialog_r.top,
      mainWndWidth,
      mainWndHeight,
      SWP_NOZORDER|SWP_NOACTIVATE
    );
    // Sets the font of IO window to be the same as the main window
    mySendMessage(hConfigWindow, WM_SETFONT, (WPARAM)hFont, TRUE);
  }
  else
  {
    popstring(NULL);
    pushstring("error creating dialog");
    return 1;
  }

  BOOL fFocused = FALSE;
  BOOL fFocusedByFlag = FALSE;

#define DEFAULT_STYLES (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS)
#define RTL_EX_STYLES (WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR)

  for (int nIdx = 0; nIdx < nNumFields; nIdx++) {
    static struct {
      char* pszClass;
      DWORD dwStyle;
      DWORD dwRTLStyle;
      DWORD dwExStyle;
      DWORD dwRTLExStyle;
    } ClassTable[] = {
      { "STATIC",       // FIELD_LABEL
        DEFAULT_STYLES,
        DEFAULT_STYLES | SS_RIGHT,
        WS_EX_TRANSPARENT,
        WS_EX_TRANSPARENT | RTL_EX_STYLES },
      { "STATIC",       // FIELD_ICON
        DEFAULT_STYLES | SS_ICON,
        DEFAULT_STYLES | SS_ICON,
        0,
        RTL_EX_STYLES },
      { "STATIC",       // FIELD_BITMAP
        DEFAULT_STYLES | SS_BITMAP,
        DEFAULT_STYLES | SS_BITMAP,
        0,
        RTL_EX_STYLES },
      { "BUTTON",       // FIELD_BROWSEBUTTON
        DEFAULT_STYLES | WS_TABSTOP,
        DEFAULT_STYLES | WS_TABSTOP,
        0,
        RTL_EX_STYLES },
      { "BUTTON",       // FIELD_LINK
        DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW,
        DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW | BS_RIGHT,
        0,
        RTL_EX_STYLES },
      { "BUTTON",       // FIELD_BUTTON
        DEFAULT_STYLES | WS_TABSTOP,
        DEFAULT_STYLES | WS_TABSTOP,
        0,
        RTL_EX_STYLES },
      { "BUTTON",       // FIELD_GROUPBOX
        DEFAULT_STYLES | BS_GROUPBOX,
        DEFAULT_STYLES | BS_GROUPBOX | BS_RIGHT,
        WS_EX_TRANSPARENT,
        WS_EX_TRANSPARENT | RTL_EX_STYLES },
      { "BUTTON",       // FIELD_CHECKBOX
        DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTOCHECKBOX | BS_MULTILINE,
        DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTOCHECKBOX | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT,
        0,
        RTL_EX_STYLES },
      { "BUTTON",       // FIELD_RADIOBUTTON
        DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTORADIOBUTTON | BS_MULTILINE,
        DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTORADIOBUTTON | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT,
        0,
        RTL_EX_STYLES },
      { "EDIT",         // FIELD_TEXT
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL,
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | RTL_EX_STYLES },
      { "EDIT",         // FIELD_FILEREQUEST
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL,
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | RTL_EX_STYLES },
      { "EDIT",         // FIELD_DIRREQUEST
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL,
        DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | RTL_EX_STYLES },
      { "COMBOBOX",     // FIELD_COMBOBOX
        DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | CBS_AUTOHSCROLL | CBS_HASSTRINGS,
        DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | CBS_AUTOHSCROLL | CBS_HASSTRINGS,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RIGHT | RTL_EX_STYLES },
      { "LISTBOX",      // FIELD_LISTBOX
        DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT,
        DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RIGHT | RTL_EX_STYLES }
    };

    FieldType *pField = pFields + nIdx;

#undef DEFAULT_STYLES

    if (pField->nType < 1 || pField->nType > (sizeof(ClassTable) / sizeof(ClassTable[0])))
      continue;

    DWORD dwStyle, dwExStyle;
    if (bRTL) {
      dwStyle = ClassTable[pField->nType - 1].dwRTLStyle;
      dwExStyle = ClassTable[pField->nType - 1].dwRTLExStyle;
    }
    else {
      dwStyle = ClassTable[pField->nType - 1].dwStyle;
      dwExStyle = ClassTable[pField->nType - 1].dwExStyle;
    }

    // Convert from dialog units

    RECT rect = pField->rect;
    // MapDialogRect uses the font used when a dialog is created, and ignores
    // any subsequent WM_SETFONT messages (like we used above); so use the main
    // NSIS window for the conversion, instead of this one.
    MapDialogRect(mainwnd, &rect);

    if (pField->rect.left < 0)
      rect.left += mainWndWidth;
    if (pField->rect.right < 0)
      rect.right += mainWndWidth;
    if (pField->rect.top < 0)
      rect.top += mainWndHeight;
    if (pField->rect.bottom < 0)
      rect.bottom += mainWndHeight;

    if (bRTL) {
      int right = rect.right;
      rect.right = mainWndWidth - rect.left;
      rect.left = mainWndWidth - right;
    }

    char *title = pField->pszText;
    switch (pField->nType) {
      case FIELD_ICON:
      case FIELD_BITMAP:
        title = NULL; // otherwise it is treated as the name of a resource
        break;
      case FIELD_CHECKBOX:
      case FIELD_RADIOBUTTON:
        dwStyle ^= pField->nFlags & BS_LEFTTEXT;
        break;
      case FIELD_TEXT:
      case FIELD_FILEREQUEST:
      case FIELD_DIRREQUEST:
        if (pField->nFlags & FLAG_PASSWORD)
          dwStyle |= ES_PASSWORD;
        if (pField->nFlags & FLAG_ONLYNUMBERS)
          dwStyle |= ES_NUMBER;
        if (pField->nFlags & FLAG_WANTRETURN)
          dwStyle |= ES_WANTRETURN;
        if (pField->nFlags & FLAG_READONLY)
          dwStyle |= ES_READONLY;
        title = pField->pszState;
        if (pField->nFlags & FLAG_MULTILINE)
        {
          dwStyle |= ES_MULTILINE | ES_AUTOVSCROLL;
          // Enable word-wrap unless we have a horizontal scroll bar
          // or it has been explicitly disallowed
          if (!(pField->nFlags & (WS_HSCROLL | FLAG_NOWORDWRAP)))
            dwStyle &= ~ES_AUTOHSCROLL;
          ConvertNewLines(pField->pszState);
          // If multiline-readonly then hold the text back until after the
          // initial focus has been set. This is so the text is not initially
          // selected - useful for License Page look-a-likes.
          if (pField->nFlags & FLAG_READONLY)
            title = NULL;
        }
        break;
      case FIELD_COMBOBOX:
        dwStyle |= (pField->nFlags & FLAG_DROPLIST) ? CBS_DROPDOWNLIST : CBS_DROPDOWN;
        title = pField->pszState;
        break;
      case FIELD_LISTBOX:
        dwStyle |= pField->nFlags & (LBS_NOTIFY | LBS_MULTIPLESEL | LBS_EXTENDEDSEL);
        break;
    }

    dwStyle |= pField->nFlags & (WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_DISABLED);
    if (pField->nFlags & WS_TABSTOP) dwStyle &= ~WS_TABSTOP;

    HWND hwCtrl = pField->hwnd = CreateWindowEx(
      dwExStyle,
      ClassTable[pField->nType - 1].pszClass,
      title,
      dwStyle,
      rect.left,
      rect.top,
      rect.right - rect.left,
      rect.bottom - rect.top,
      hConfigWindow,
      (HMENU)pField->nControlID,
      m_hInstance,
      NULL
    );

    {
      char szField[64];
      char szHwnd[64];
      wsprintf(szField, "Field %d", pField->nField);
      wsprintf(szHwnd, "%d", hwCtrl);
      WritePrivateProfileString(szField, pField->pszHwndEntry, szHwnd, pszFilename);
    }

    if (hwCtrl) {
      // Sets the font of IO window to be the same as the main window
      mySendMessage(hwCtrl, WM_SETFONT, (WPARAM)hFont, TRUE);
      // make sure we created the window, then set additional attributes
      switch (pField->nType) {
        case FIELD_TEXT:
        case FIELD_FILEREQUEST:
        case FIELD_DIRREQUEST:
          mySendMessage(hwCtrl, EM_LIMITTEXT, (WPARAM)pField->nMaxLength, (LPARAM)0);
          if (dwStyle & ES_NUMBER)
          {
            pField->wndProc = GetWindowLong(hwCtrl, GWL_WNDPROC);
            SetWindowLong(hwCtrl, GWL_WNDPROC, (long) NumbersOnlyPasteWndProc);
          }
          break;

        case FIELD_CHECKBOX:
        case FIELD_RADIOBUTTON:
          if (pField->pszState[0] == '1')
            mySendMessage(hwCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
          break;

        case FIELD_COMBOBOX:
        case FIELD_LISTBOX:
          // if this is a listbox or combobox, we need to add the list items.
          if (pField->pszListItems) {
            UINT nAddMsg, nFindMsg, nSetSelMsg;
            if (pField->nType == FIELD_COMBOBOX) {
              nAddMsg = CB_ADDSTRING;
              nFindMsg = CB_FINDSTRINGEXACT;
              nSetSelMsg = CB_SETCURSEL;
            }
            else {
              nAddMsg = LB_ADDSTRING;
              nFindMsg = LB_FINDSTRINGEXACT;
              nSetSelMsg = LB_SETCURSEL;
            }
            char *pszStart, *pszEnd, *pszList;
            pszStart = pszEnd = pszList = STRDUP(pField->pszListItems);
            // pszListItems has a trailing pipe
            while (*pszEnd) {
              if (*pszEnd == '|') {
                *pszEnd = '\0';
                if (*pszStart)
                  mySendMessage(hwCtrl, nAddMsg, 0, (LPARAM) pszStart);
                pszStart = ++pszEnd;
              }
              else
                pszEnd = CharNext(pszEnd);
            }
            FREE(pszList);
            if (pField->pszState) {
              if (pField->nFlags & (LBS_MULTIPLESEL|LBS_EXTENDEDSEL) && nFindMsg == LB_FINDSTRINGEXACT) {
                mySendMessage(hwCtrl, LB_SETSEL, FALSE, (LPARAM)-1);
                pszStart = pszEnd = pField->pszState;
                for (;;) {
                  char c = *pszEnd;
                  if (c == '|' || c == '\0') {
                    *pszEnd = '\0';
                    if (*pszStart)
                    {
                      int nItem = mySendMessage(hwCtrl, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)pszStart);
                      if (nItem != LB_ERR)
                        mySendMessage(hwCtrl, LB_SETSEL, TRUE, nItem);
                    }
                    if (!c)
                      break;
                    pszStart = ++pszEnd;
                  }
                  else
                    pszEnd = CharNext(pszEnd);
                }
              }
              else {
                int nItem = mySendMessage(hwCtrl, nFindMsg, (WPARAM)-1, (LPARAM)pField->pszState);
                if (nItem != CB_ERR) { // CB_ERR == LB_ERR == -1
                  mySendMessage(hwCtrl, nSetSelMsg, nItem, 0);
                }
              }
            }
          }
          break;

        case FIELD_ICON:
        case FIELD_BITMAP:
        {
          WPARAM nImageType = pField->nType == FIELD_BITMAP ? IMAGE_BITMAP : IMAGE_ICON;
          LPARAM nImage = 0;

          if (pField->pszText) {
            pField->hImage = LoadImage(
              m_hInstance,
              pField->pszText,
              nImageType,
              (pField->nFlags & FLAG_RESIZETOFIT)
                ? (rect.right - rect.left)
                : 0,
              (pField->nFlags & FLAG_RESIZETOFIT)
                ? (rect.bottom - rect.top)
                : 0,
              LR_LOADFROMFILE
            );
            nImage = (LPARAM)pField->hImage;
          }
          else
            nImage = (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(103));

          if ((pField->nFlags & TRANSPARENT_BMP) && nImageType == IMAGE_BITMAP)
          {
            // based on AdvSplash's SetTransparentRegion
            BITMAP bm;
            HBITMAP hBitmap = (HBITMAP) nImage;

            if (GetObject(hBitmap, sizeof(bm), &bm))
            {
              HDC dc;
              int x, y;
              HRGN region, cutrgn;
              BITMAPINFO bmi;
              int size = bm.bmWidth * bm.bmHeight * sizeof(int);
              int *bmp = (int *) MALLOC(size);
              if (bmp)
              {
                bmi.bmiHeader.biBitCount = 32;
                bmi.bmiHeader.biCompression = BI_RGB;
                bmi.bmiHeader.biHeight = bm.bmHeight;
                bmi.bmiHeader.biPlanes = 1;
                bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
                bmi.bmiHeader.biWidth = bm.bmWidth;
                bmi.bmiHeader.biClrUsed = 0;
                bmi.bmiHeader.biClrImportant = 0;

                dc = CreateCompatibleDC(NULL);
                SelectObject(dc, hBitmap);

                x = GetDIBits(dc, hBitmap, 0, bm.bmHeight, bmp, &bmi, DIB_RGB_COLORS);

                region = CreateRectRgn(0, 0, bm.bmWidth, bm.bmHeight);

                int keycolor = *bmp & 0xFFFFFF;

                // Search for transparent pixels 
                for (y = bm.bmHeight - 1; y >= 0; y--) {
                  for (x = 0; x < bm.bmWidth;) {
                    if ((*bmp & 0xFFFFFF) == keycolor) {
                      int j = x;
                      while ((x < bm.bmWidth) && ((*bmp & 0xFFFFFF) == keycolor)) {
                        bmp++, x++;
                      }

                      // Cut transparent pixels from the original region
                      cutrgn = CreateRectRgn(j, y, x, y + 1);
                      CombineRgn(region, region, cutrgn, RGN_XOR);
                      DeleteObject(cutrgn);
                    } else {
                      bmp++, x++;
                    }
                  }
                }

                // Set resulting region.
                SetWindowRgn(hwCtrl, region, TRUE);
                DeleteObject(region);
                DeleteObject(dc);
                FREE(bmp);
              }
            }
          }

          mySendMessage(
            hwCtrl,
            STM_SETIMAGE,
            nImageType,
            nImage
          );

          if (pField->nType == FIELD_BITMAP)
          {
            // Centre the image in the requested space.
            // Cannot use SS_CENTERIMAGE because it behaves differently on XP to
            // everything else.  (Thank you Microsoft.)
            RECT  bmp_rect;
            GetClientRect(hwCtrl, &bmp_rect);
            bmp_rect.left = (rect.left + rect.right - bmp_rect.right) / 2;
            bmp_rect.top = (rect.top + rect.bottom - bmp_rect.bottom) / 2;
            SetWindowPos(hwCtrl, NULL, bmp_rect.left, bmp_rect.top, 0, 0,
                         SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
          }

          break;
        }

#ifdef IO_ENABLE_LINK
        case FIELD_LINK:
          pField->nParentIdx = SetWindowLong(hwCtrl, GWL_WNDPROC, (long)StaticLINKWindowProc);
          break;
#endif
      }

      // Set initial focus to the first appropriate field ( with FOCUS flag)
      if (!fFocusedByFlag && (dwStyle & (WS_TABSTOP | WS_DISABLED)) == WS_TABSTOP && pField->nType >= FIELD_SETFOCUS) {
        if (pField->nFlags & FLAG_FOCUS) {
          fFocusedByFlag = TRUE;
        }
        if (!fFocused || fFocusedByFlag) {
          fFocused = TRUE;
          mySetFocus(hwCtrl);
        }
      }

      // If multiline-readonly then hold the text back until after the
      // initial focus has been set. This is so the text is not initially
      // selected - useful for License Page look-a-likes.
      if ((pField->nFlags & (FLAG_MULTILINE | FLAG_READONLY)) == (FLAG_MULTILINE | FLAG_READONLY))
        mySetWindowText(hwCtrl, pField->pszState);
    }
  }

  if (!fFocused)
    mySetFocus(hNextButton);

  mySetWindowText(mainwnd,pszTitle);
  pFilenameStackEntry = *g_stacktop;
  *g_stacktop = (*g_stacktop)->next;
  static char tmp[32];
  wsprintf(tmp,"%d",hConfigWindow);
  pushstring(tmp);
  return 0;
}
Esempio n. 5
0
//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		case IDB_BUTTON:
			
			break;
		case IDB_BUTTON_CONNECT:
			TCHAR ip_port[MAX_NUM_BUF];
			memset(ip_port,0,MAX_NUM_BUF);
			GetWindowText(ipEditHwnd, ip_port, MAX_NUM_BUF);
			strcpy_s(ip, sizeof(ip), ip_port);
			memset(ip_port,0,MAX_NUM_BUF);
			GetWindowText(portEditHwnd, ip_port, MAX_NUM_BUF);
			port = atoi(ip_port);

			if(connectStatus != TRUE)//还未连接服务器,现在连接
			{
				// Windows Sockets 动态库的初始化
				InitDll(hWnd);
				//创建SOCKET
				InitSocket(clientSocket, hWnd);
				// 连接服务器
				connectServer(hWnd);
			}
			if(connectStatus != TRUE)
			{
				mySetWindowText("连接服务器失败");
				break;
			}
			break;
		case IDB_BUTTON_SEND:
		{
			if (connectStatus == FALSE)
			{
				mySetWindowText("还没连接,别乱发数据");
				break;
			}
			// 设置和获取文本框里的内容
			TCHAR editTextBuffer[MAX_NUM_BUF];
			memset(editTextBuffer,0,MAX_NUM_BUF);
			GetWindowText(sendEditHwnd, editTextBuffer, MAX_NUM_BUF);
			int ret = sendLine(clientSocket, editTextBuffer, hWnd);
			if (SOCKET_ERROR == ret)
			{
				mySetWindowText("发送失败");
				break;
			}
			break;
		}
		case IDB_BUTTON_CLOSE:
		{
			// 如果已经关闭 不作反应
			if (connectStatus == FALSE)
			{
				mySetWindowText("client has stopped");
				break;
			}
			sendLine(clientSocket, "close", hWnd);
			int ret = closeService(clientSocket);
			if(SOCKET_ERROR == ret)
			{
				mySetWindowText("client closesocket fail");
				break;
			}else if (TRUE == ret)
			{
				mySetWindowText("客户端关闭socket成功");
				break;
			} 
			mySetWindowText("服务器关闭不成功,但是怎么失败的我也不知道");
			break;
		}
			
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;

	case WM_LBUTTONDOWN:
		{
			// 设置和获取文本框里的内容
			/*
			TCHAR editTextBuffer[MAX_NUM_BUF];
			GetWindowText(receiveEditHwnd, editTextBuffer, MAX_NUM_BUF);
			HDC hdc = GetDC(hWnd);
			TCHAR newTextStr[MAX_NUM_BUF];
			wsprintf(newTextStr,TEXT("%s - %s"),editTextBuffer,"receiveEditHwnd");
			SetWindowText(receiveEditHwnd, newTextStr);
			*/
		
			break;
		}
		
	case WM_CREATE:
		{
			receiveEditHwnd = CreateWindow("edit", NULL,
				WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_MULTILINE ,
				30, 80, 300, 200, hWnd, (HMENU)HMENU_ID, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);
	
			sendEditHwnd = CreateWindow("edit", NULL,
				WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_MULTILINE ,
				30, 370, 300, 50, hWnd, (HMENU)HMENU_ID, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);

			ipEditHwnd = CreateWindow("edit", TEXT("192.168.1.101"),
				WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_MULTILINE ,
				50, 430, 130, 30, hWnd, (HMENU)HMENU_ID, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);
			
			portEditHwnd = CreateWindow("edit", TEXT("5419"),
				WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_MULTILINE ,
				240, 430, 60, 30, hWnd, (HMENU)HMENU_ID, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);
			
			buttonConnect = CreateWindow("button", TEXT("连接服务"),
				WS_CHILD | WS_VISIBLE | WS_BORDER  ,
				30, 470, 90, 30, hWnd, (HMENU)IDB_BUTTON_CONNECT, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);

			buttonSend = CreateWindow("button", TEXT("发送数据"),
				WS_CHILD | WS_VISIBLE | WS_BORDER  ,
				130, 470, 90, 30, hWnd, (HMENU)IDB_BUTTON_SEND, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);

			buttonClose = CreateWindow("button", TEXT("断开服务"),
				WS_CHILD | WS_VISIBLE | WS_BORDER  ,
				230, 470, 90, 30, hWnd, (HMENU)IDB_BUTTON_CLOSE, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);

			buttonHwnd = CreateWindow("button", TEXT("B"),
				WS_CHILD | WS_VISIBLE | WS_BORDER  ,
				240, 10, 30, 20, hWnd, (HMENU)IDB_BUTTON, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);

			break;
		}
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}