コード例 #1
0
ファイル: Ui.c プロジェクト: kichik/nsis-1
static INT_PTR CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  page *m_this_page=g_this_page;
  HWND hwLicense;
#define LicIgnoreWMCommand g_cbLicRead // g_cbLicRead is only used in WM_INITDIALOG during EM_STREAMIN

  if (uMsg == WM_INITDIALOG)
  {
    TCHAR *l = (TCHAR *)GetNSISStringNP(GetNSISTab(this_page->parms[1]));
    int lt = *l;
    EDITSTREAM es = {
      (DWORD_PTR)(++l),
      0,
#ifdef _UNICODE
      lt==SF_RTF?StreamLicenseRTF:StreamLicense
#else
      StreamLicense
#endif
    };

    int selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION);

    SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]);
    SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]);
    CheckDlgButton(hwndDlg,IDC_LICENSEAGREE+!selected,BST_CHECKED);
    EnableNext(selected);

    hwLicense=GetUIItem(IDC_EDIT1);
    SetActiveCtl(hwLicense);
    SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0);
#define lbg g_header->license_bg
    SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg));
#undef lbg
    SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS
    SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l));
    g_cbLicRead = 0;
    SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es);
    LicIgnoreWMCommand = 0;
    return FALSE;
  }
  if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && !LicIgnoreWMCommand) {
    if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) {
      int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED;
      m_this_page->flags &= ~PF_LICENSE_SELECTED;
      m_this_page->flags |= is;
      EnableNext(is);
      SetNextDef();
    }
  }
  if (uMsg == WM_NOTIFY) {
    hwLicense=GetUIItem(IDC_EDIT1);
    #define nmhdr ((NMHDR *)lParam)
    #define enlink ((ENLINK *)lParam)
    #define msgfilter ((MSGFILTER *)lParam)
    if (nmhdr->code==EN_LINK) {
      if (enlink->msg==WM_LBUTTONDOWN) {
        TEXTRANGE tr = {
          {
            enlink->chrg.cpMin,
            enlink->chrg.cpMax,
          },
          ps_tmpbuf
        };
        if (tr.chrg.cpMax-tr.chrg.cpMin < COUNTOF(ps_tmpbuf)) {
          SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr);
          SetCursor(LoadCursor(0, IDC_WAIT));
          ShellExecute(hwndDlg,_T("open"),tr.lpstrText,NULL,NULL,SW_SHOWNORMAL);
          SetCursor(LoadCursor(0, IDC_ARROW));
        }
      }
    }
    //Ximon Eighteen 8th September 2002 Capture return key presses in the rich
    //edit control now that the control gets the focus rather than the default
    //push button. When the user presses return ask the outer dialog to move
    //the installer onto the next page. MSDN docs say return non-zero if the
    //rich edit control should NOT process this message, hence the return 1.
    //
    //This is required because the RichEdit control is eating all the key hits.
    //It does try to release some and convert VK_ESCAPE to WM_CLOSE, VK_ENTER
    //to a push on the default button and VM_TAB to WM_NEXTDLGCTL. But sadly it
    //it sends all of these messages to its parent instead of just letting the
    //dialog manager handle them. Instead of properly handling WM_GETDLGCODE,
    //it mimics the dialog manager.
    if (nmhdr->code==EN_MSGFILTER)
    {
      if (msgfilter->msg==WM_KEYDOWN)
      {
        if (msgfilter->wParam==VK_RETURN) {
          SendMessage(g_hwnd, WM_COMMAND, IDOK, 0);
        }
        if (msgfilter->wParam==VK_ESCAPE) {
          SendMessage(g_hwnd, WM_CLOSE, 0, 0);
        }
        return 1;
      }
    }
    #undef nmhdr
    #undef enlink
    #undef msgfilter
  }
  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    LicIgnoreWMCommand++;
  }
  return HandleStaticBkColor();
}
コード例 #2
0
ファイル: Ui.c プロジェクト: kichik/nsis-1
static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static int dontsetdefstyle;
  page *thispage = g_this_page;
  TCHAR *dir = g_usrvars[thispage->parms[4]];
  int browse_text = thispage->parms[3];

  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    GetUIText(IDC_DIR,dir);
    validate_filename(dir);
#ifdef NSIS_CONFIG_LOG
#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
    build_g_logfile();
#endif
    if (GetUIItem(IDC_CHECK1) != NULL)
      log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
#endif
  }
  if (uMsg == WM_INITDIALOG)
  {
    HWND hDir = GetUIItem(IDC_DIR);

#ifdef NSIS_CONFIG_LOG
    if (GetAsyncKeyState(VK_SHIFT)&0x8000)
    {
      HWND h=GetUIItem(IDC_CHECK1);
      SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS);
      ShowWindow(h,SW_SHOWNA);
    }
#endif
    if (validpathspec(dir) && !skip_root(dir))
      addtrailingslash(dir);

    // workaround for bug #1209843
    //
    // m_curwnd is only updated once WM_INITDIALOG returns.
    // my_SetWindowText triggers an EN_CHANGE message that
    // triggers a WM_IN_UPDATEMSG message that uses m_curwnd
    // to get the selected directory (GetUIText).
    // because m_curwnd is still outdated, dir varialble is
    // filled with an empty string. by default, dir points
    // to $INSTDIR.
    //
    // to solve this, m_curwnd is manually set to the correct
    // window handle.

    m_curwnd=hwndDlg;

    my_SetWindowText(hDir,dir);
    SetUITextFromLang(IDC_BROWSE,this_page->parms[2]);
    SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]);
    SetActiveCtl(hDir);

    {
      typedef HRESULT (WINAPI *SHAutoCompletePtr)(HWND, DWORD);
      SHAutoCompletePtr fSHAutoComplete;
      fSHAutoComplete = (SHAutoCompletePtr) myGetProcAddress(MGA_SHAutoComplete);
      if (fSHAutoComplete)
      {
        fSHAutoComplete(hDir, SHACF_FILESYSTEM);
      }
    }
  }
  if (uMsg == WM_COMMAND)
  {
    int id=LOWORD(wParam);
    if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
    {
      uMsg = WM_IN_UPDATEMSG;
    }
    if (id == IDC_BROWSE)
    {
      static TCHAR bt[NSIS_MAX_STRLEN];
      BROWSEINFO bi = {0,};
      ITEMIDLIST *idlist;
      bi.hwndOwner = hwndDlg;
      bi.pszDisplayName = g_tmp;
      bi.lpfn = BrowseCallbackProc;
      bi.lParam = (LPARAM)dir;
      bi.lpszTitle = GetNSISString(bt, browse_text);
      bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
      idlist = SHBrowseForFolder(&bi);
      if (idlist)
      {
        // free idlist
        CoTaskMemFree(idlist);

        addtrailingslash(dir);

        if (g_header->install_directory_auto_append &&
          dir == state_install_directory) // only append to $INSTDIR (bug #1174184)
        {
          const TCHAR *post_str = ps_tmpbuf;
          GetNSISStringTT(g_header->install_directory_auto_append);
          // display name gives just the folder name
          if (lstrcmpi(post_str, g_tmp))
          {
            mystrcat(dir, post_str);
          }
        }

        dontsetdefstyle++;
        SetUITextNT(IDC_DIR,dir);
      }
      else
      {
        uMsg = WM_IN_UPDATEMSG;
      }
    }
  }
  if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START)
  {
    static TCHAR s[NSIS_MAX_STRLEN];
    int error = 0;
    int available_set = 0;
    unsigned total, available;

    GetUIText(IDC_DIR,dir);
    if (!is_valid_instpath(dir))
      error = NSIS_INSTDIR_INVALID;

    /**
     * This part is tricky. We need to make sure a few things:
     *
     *   1. GetDiskFreeSpaceEx is always called at least once for large HD.
     *        Even if skip_root() returned NULL (e.g. "C:").
     *        Note that trimslashtoend() will nullify "C:".
     *   2. GetDiskFreeSpaceEx is called with the deepest valid directory.
     *        e.g. C:\drive when the user types C:\drive\folder1\folder2.
     *        This makes sure NTFS mount points are treated properly (#1946112).
     *   3. `s' stays valid after the loop for GetDiskFreeSpace.
     *        This means there is no cutting beyond what skip_root() returns.
     *        Or `s' could be recreated when GetDiskFreeSpace is called.
     *   4. If GetDiskFreeSpaceEx doesn't exist, GetDiskFreeSpace is used.
     *   5. Both functions require a trailing backslash
     *   6. `dir' is never modified.
     *
     */
    mystrcpy(s,dir);

    // Test for and use the GetDiskFreeSpaceEx API
    {
      BOOL (WINAPI *GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
          myGetProcAddress(MGA_GetDiskFreeSpaceEx);
      if (GDFSE)
      {
        ULARGE_INTEGER available64;
        ULARGE_INTEGER a, b;
        TCHAR *p;
        TCHAR *pw = NULL;
        while (pw != s) // trimslashtoend() cut the entire string
        {
          if (GDFSE(s, &available64, &a, &b))
          {
#ifndef _NSIS_NO_INT64_SHR
            available = (int)(available64.QuadPart >> 10);
#else
            available = (int)(Int64ShrlMod32(available64.QuadPart, 10));
#endif
            available_set++;
            break;
          }

          if (pw)
            // if pw was set, remove the backslash so trimslashtoend() will cut a new one
            *pw = 0;

          p = trimslashtoend(s); // trim last backslash
          // bring it back, but make the next char null
          pw = p;
          *pw = 0;
          --pw;
          *pw = _T('\\'); 
        }
      }
    }

    if (!available_set)
    {
      DWORD spc, bps, fc, tc;
      TCHAR *root;

      // GetDiskFreeSpaceEx accepts any path, but GetDiskFreeSpace accepts only the root
      mystrcpy(s,dir);
      root=skip_root(s);
      if (root)
        *root=0;

      // GetDiskFreeSpaceEx is not available
      if (GetDiskFreeSpace(s, &spc, &bps, &fc, &tc))
      {
        available = (int)MulDiv(bps * spc, fc, 1 << 10);
        available_set++;
      }
    }

    total = (unsigned) sumsecsfield(size_kb);

#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // available_set is checked first so available is initialized
#endif
    if (available_set && available < total)
      error = NSIS_INSTDIR_NOT_ENOUGH_SPACE;
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif

    if (LANG_STR_TAB(LANG_SPACE_REQ)) {
      SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,total);
      if (available_set)
        SetSizeText(IDC_SPACEAVAILABLE,LANG_SPACE_AVAIL,available);
      else
        SetUITextNT(IDC_SPACEAVAILABLE,_T(""));
    }

    g_exec_flags.instdir_error = error;

#ifdef NSIS_SUPPORT_CODECALLBACKS
    if (!error)
      error = ExecuteCallbackFunction(CB_ONVERIFYINSTDIR);
#endif

    if (thispage->flags & PF_DIR_NO_BTN_DISABLE)
      error = 0;

    EnableNext(!error);
    if (!error && !dontsetdefstyle)
      SetNextDef();
    dontsetdefstyle = 0;
  }
コード例 #3
0
ファイル: Ui.c プロジェクト: kichik/nsis-1
static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static int dontsetdefstyle;
  page *thispage = g_this_page;
  TCHAR *dir = g_usrvars[thispage->parms[4]];
  int browse_text = thispage->parms[3];
  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    GetUIText(IDC_DIR,dir);
    validate_filename(dir);
#ifdef NSIS_CONFIG_LOG
#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
    build_g_logfile();
#endif
    if (GetUIItem(IDC_CHECK1) != NULL)
      log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
#endif
  }
  if (uMsg == WM_INITDIALOG)
  {
    HWND hDir = GetUIItem(IDC_DIR);

#ifdef NSIS_CONFIG_LOG
    if (GetAsyncKeyState(VK_SHIFT)&0x8000)
    {
      HWND h=GetUIItem(IDC_CHECK1);
      SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS);
      ShowWindow(h,SW_SHOWNA);
    }
#endif
    if (validpathspec(dir) && !skip_root(dir))
      addtrailingslash(dir);

    // workaround for bug #1209843
    //
    // m_curwnd is only updated once WM_INITDIALOG returns.
    // my_SetWindowText triggers an EN_CHANGE message that
    // triggers a WM_IN_UPDATEMSG message that uses m_curwnd
    // to get the selected directory (GetUIText).
    // because m_curwnd is still outdated, dir varialble is
    // filled with an empty string. by default, dir points
    // to $INSTDIR.
    //
    // to solve this, m_curwnd is manually set to the correct
    // window handle.

    m_curwnd=hwndDlg;

    my_SetWindowText(hDir,dir);
    SetUITextFromLang(IDC_BROWSE,this_page->parms[2]);
    SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]);
    SetActiveCtl(hDir);

    {
      typedef HRESULT (WINAPI *SHAutoCompletePtr)(HWND, DWORD);
      SHAutoCompletePtr fSHAutoComplete;
      static const TCHAR shlwapi[] = TEXT("shlwapi.dll");
      static const char shac[] = "SHAutoComplete";
      fSHAutoComplete = (SHAutoCompletePtr) myGetProcAddress((TCHAR *)shlwapi, (char *) shac);
      if (fSHAutoComplete)
      {
        fSHAutoComplete(hDir, SHACF_FILESYSTEM);
      }
    }
  }
  if (uMsg == WM_COMMAND)
  {
    int id=LOWORD(wParam);
    if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
    {
      uMsg = WM_IN_UPDATEMSG;
    }
    if (id == IDC_BROWSE)
    {
      static TCHAR bt[NSIS_MAX_STRLEN];
      BROWSEINFO bi = {0,};
      ITEMIDLIST *idlist;
      bi.hwndOwner = hwndDlg;
      bi.pszDisplayName = g_tmp;
      bi.lpfn = BrowseCallbackProc;
      bi.lParam = (LPARAM)dir;
      bi.lpszTitle = GetNSISString(bt, browse_text);
      bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
      idlist = SHBrowseForFolder(&bi);
      if (idlist)
      {
        // free idlist
        FreePIDL(idlist);

        addtrailingslash(dir);

        if (g_header->install_directory_auto_append &&
          dir == state_install_directory) // only append to $INSTDIR (bug #1174184)
        {
          const TCHAR *post_str = ps_tmpbuf;
          GetNSISStringTT(g_header->install_directory_auto_append);
          // display name gives just the folder name
          if (lstrcmpi(post_str, g_tmp))
          {
            mystrcat(dir, post_str);
          }
        }

        dontsetdefstyle++;
        SetUITextNT(IDC_DIR,dir);
      }
      else
      {
        uMsg = WM_IN_UPDATEMSG;
      }
    }
  }
  if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START)
  {
    static TCHAR s[NSIS_MAX_STRLEN];
    TCHAR *p;
    int error = 0;
    int available_set = 0;
    unsigned total, available = 0xFFFFFFFF;

    GetUIText(IDC_DIR,dir);
    if (!is_valid_instpath(dir))
      error = NSIS_INSTDIR_INVALID;

    mystrcpy(s,dir);
    p=skip_root(s);
    if (p)
      *p=0;

    // Test for and use the GetDiskFreeSpaceEx API
    {
#ifdef UNICODE
			BOOL (WINAPI *GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
          myGetProcAddress(L"KERNEL32.dll", "GetDiskFreeSpaceExW");
#else
      BOOL (WINAPI *GDFSE)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
          myGetProcAddress("KERNEL32.dll", "GetDiskFreeSpaceExA");
#endif
      if (GDFSE)
      {
        ULARGE_INTEGER available64;
        ULARGE_INTEGER a, b;
        if (GDFSE(s, &available64, &a, &b))
        {
#ifndef _NSIS_NO_INT64_SHR
          available = (int)(available64.QuadPart >> 10);
#else
          available = (int)(Int64ShrlMod32(available64.QuadPart, 10));
#endif
          available_set++;
        }
      }
    }

    if (!available_set)
    {
      // GetDiskFreeSpaceEx is not available
      DWORD spc, bps, fc, tc;
      if (GetDiskFreeSpace(s, &spc, &bps, &fc, &tc))
      {
        available = (int)MulDiv(bps * spc, fc, 1 << 10);
        available_set++;
      }
    }

    total = (unsigned) sumsecsfield(size_kb);

    if (available < total)
      error = NSIS_INSTDIR_NOT_ENOUGH_SPACE;

    if (LANG_STR_TAB(LANG_SPACE_REQ)) {
      SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,total);
      if (available_set)
        SetSizeText(IDC_SPACEAVAILABLE,LANG_SPACE_AVAIL,available);
      else
        SetUITextNT(IDC_SPACEAVAILABLE,TEXT(""));
    }

    g_exec_flags.instdir_error = error;

#ifdef NSIS_SUPPORT_CODECALLBACKS
    if (!error)
      error = ExecuteCallbackFunction(CB_ONVERIFYINSTDIR);
#endif

    if (thispage->flags & PF_DIR_NO_BTN_DISABLE)
      error = 0;

    EnableNext(!error);
    if (!error && !dontsetdefstyle)
      SetNextDef();
    dontsetdefstyle = 0;
  }
コード例 #4
0
ファイル: Ui.c プロジェクト: kichik/nsis-1
static INT_PTR CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  page *m_this_page=g_this_page;
  HWND hwLicense;
  static int ignoreWMCommand;

  if (uMsg == WM_INITDIALOG)
  {
    TCHAR *l = (TCHAR *)GetNSISStringNP(GetNSISTab(this_page->parms[1]));
    int lt = *l;
    EDITSTREAM es = {
      (DWORD_PTR)(++l),
      0,
      StreamLicense
    };

    int selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION);

    SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]);
    SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]);
    CheckDlgButton(hwndDlg,IDC_LICENSEAGREE+!selected,BST_CHECKED);
    EnableNext(selected);

    hwLicense=GetUIItem(IDC_EDIT1);
    SetActiveCtl(hwLicense);
    SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0);
#define lbg g_header->license_bg
    SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg));
#undef lbg
    SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS
    dwRead=0;
    SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l));
    SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es);
    ignoreWMCommand = 0;
    return FALSE;
  }
  if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && !ignoreWMCommand) {
    if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) {
      int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED;
      m_this_page->flags &= ~PF_LICENSE_SELECTED;
      m_this_page->flags |= is;
      EnableNext(is);
      SetNextDef();
    }
  }
  if (uMsg == WM_NOTIFY) {
    hwLicense=GetUIItem(IDC_EDIT1);
    #define nmhdr ((NMHDR *)lParam)
    #define enlink ((ENLINK *)lParam)
    #define msgfilter ((MSGFILTER *)lParam)
    if (nmhdr->code==EN_LINK) {
      if (enlink->msg==WM_LBUTTONDOWN) {
        TEXTRANGE tr = {
          {
            enlink->chrg.cpMin,
            enlink->chrg.cpMax,
          },
          ps_tmpbuf
        };
        if (tr.chrg.cpMax-tr.chrg.cpMin < (sizeof(ps_tmpbuf)/sizeof(*ps_tmpbuf))) {
          SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr);
          SetCursor(LoadCursor(0, IDC_WAIT));
          ShellExecute(hwndDlg,TEXT("open"),tr.lpstrText,NULL,NULL,SW_SHOWNORMAL);
          SetCursor(LoadCursor(0, IDC_ARROW));
        }
      }
    }
    //Ximon Eighteen 8th September 2002 Capture return key presses in the rich
    //edit control now that the control gets the focus rather than the default
    //push button. When the user presses return ask the outer dialog to move
    //the installer onto the next page. MSDN docs say return non-zero if the
    //rich edit control should NOT process this message, hence the return 1.
    if (nmhdr->code==EN_MSGFILTER)
    {
      if (msgfilter->msg==WM_KEYDOWN)
      {
        if (msgfilter->wParam==VK_RETURN) {
          SendMessage(g_hwnd, WM_COMMAND, IDOK, 0);
        }
        if (msgfilter->wParam==VK_ESCAPE) {
          SendMessage(g_hwnd, WM_CLOSE, 0, 0);
        }
        return 1;
      }
    }
    #undef nmhdr
    #undef enlink
    #undef msgfilter
  }
  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    ignoreWMCommand++;
  }
  return HandleStaticBkColor();
}
コード例 #5
0
ファイル: Ui.c プロジェクト: kichik/nsis-1
static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static int dontsetdefstyle;
  page *thispage = g_this_page;
  char *dir = g_usrvars[thispage->parms[4]];
  int browse_text = thispage->parms[3];
  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    GetUIText(IDC_DIR,dir);
    validate_filename(dir);
#ifdef NSIS_CONFIG_LOG
#ifndef NSIS_CONFIG_LOG_ODS
    build_g_logfile();
#endif
    log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
#endif
  }
  if (uMsg == WM_INITDIALOG)
  {
#ifdef NSIS_CONFIG_LOG
    if (GetAsyncKeyState(VK_SHIFT)&0x8000)
    {
      HWND h=GetUIItem(IDC_CHECK1);
      SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS);
      ShowWindow(h,SW_SHOWNA);
    }
#endif
    if (validpathspec(dir) && !skip_root(dir))
      addtrailingslash(dir);
    SetUITextNT(IDC_DIR,dir);
    SetUITextFromLang(IDC_BROWSE,this_page->parms[2]);
    SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]);
    SetActiveCtl(GetUIItem(IDC_DIR));
  }
  if (uMsg == WM_COMMAND)
  {
    int id=LOWORD(wParam);
    if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
    {
      uMsg = WM_IN_UPDATEMSG;
    }
    if (id == IDC_BROWSE)
    {
      BROWSEINFO bi = {0,};
      ITEMIDLIST *idlist;
      bi.hwndOwner = hwndDlg;
      bi.pszDisplayName = g_tmp;
      bi.lpfn = BrowseCallbackProc;
      bi.lParam = (LPARAM)dir;
      bi.lpszTitle = GetNSISStringTT(browse_text);
      bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
      idlist = SHBrowseForFolder(&bi);
      if (idlist)
      {
        // free idlist
        FreePIDL(idlist);

        if (g_header->install_directory_auto_append)
        {
          const char *post_str = ps_tmpbuf;
          GetNSISStringTT(g_header->install_directory_auto_append);
          // display name gives just the folder name
          if (lstrcmpi(post_str, g_tmp))
          {
            lstrcat(addtrailingslash(dir), post_str);
          }
        }

        dontsetdefstyle++;
        SetUITextNT(IDC_DIR,dir);
      }
    }
  }
  if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START)
  {
    static char s[NSIS_MAX_STRLEN];
    char *p;
    int error = 0;
    int available_set=0;
    unsigned total, available;
    HMODULE hLib;

    GetUIText(IDC_DIR,dir);
    if (!is_valid_instpath(dir))
      error = NSIS_INSTDIR_INVALID;

    mystrcpy(s,dir);
    p=skip_root(s);
    if (p)
      *p=0;

    // Test for and use the GetDiskFreeSpaceEx API
    hLib = GetModuleHandle("KERNEL32.dll");
    if (hLib)
    {
      BOOL (WINAPI *GDFSE)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
        (void*)GetProcAddress(hLib, "GetDiskFreeSpaceExA");
      if (GDFSE)
      {
        ULARGE_INTEGER available64;
        ULARGE_INTEGER a, b;
        if (GDFSE(s, &available64, &a, &b))
        {
          available = (int)(available64.QuadPart >> 10);
          available_set++;
        }
      }

    }

    if (!available_set)
    {
      // GetDiskFreeSpaceEx is not available
      DWORD spc, bps, fc, tc;
      if (GetDiskFreeSpace(s, &spc, &bps, &fc, &tc))
      {
        available = (int)MulDiv(bps * spc, fc, 1 << 10);
        available_set++;
      }
    }

    total = (unsigned) sumsecsfield(size_kb);

    if (available < total)
      error = NSIS_INSTDIR_NOT_ENOUGH_SPACE;

    if (LANG_STR_TAB(LANG_SPACE_REQ)) {
      SetUITextNT(IDC_SPACEREQUIRED,inttosizestr(total,GetNSISString(s,LANG_SPACE_REQ)));
      // Did we get a usable value above?
      if (available >= 0)
        SetUITextNT(IDC_SPACEAVAILABLE,inttosizestr(available,GetNSISString(s,LANG_SPACE_AVAIL)));
      else
        SetUITextNT(IDC_SPACEAVAILABLE,"");
    }

    g_exec_flags.instdir_error = error;

#ifdef NSIS_SUPPORT_CODECALLBACKS
    if (!error)
      error = ExecuteCallbackFunction(CB_ONVERIFYINSTDIR);
#endif

    if (thispage->flags & PF_DIR_NO_BTN_DISABLE)
      error = 0;

    EnableNext(!error);
    if (!error && !dontsetdefstyle)
      SetNextDef();
    dontsetdefstyle = 0;
  }
コード例 #6
0
ファイル: Ui.c プロジェクト: liao0818/nsis_unicode
static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  page *m_this_page=g_this_page;
  HWND hwLicense;
  static int ignoreWMCommand;
  EDITSTREAM es;
  es.dwError = 0;

  if (uMsg == WM_INITDIALOG)
  {
    TCHAR *l = (TCHAR *)GetNSISStringNP(GetNSISTab(this_page->parms[1]));
    // First char contains SF_RTF or SF_TEXT (SF_UNICODE)
    int lt = *l;
    int selected;

    bCookieNuked = FALSE;
    // SF_UNICODE is never set for ANSI NSIS
    if (lt & SF_UNICODE)
    {
      es.dwCookie = (DWORD_PTR)(++l);
      es.pfnCallback = StreamLicenseW;
    }
    else
    {
      es.pfnCallback = StreamLicenseA;
#ifdef _UNICODE
      {
         // If Unicode support, then even though this is straight ASCII coming
         // in, it was encoded as WCHAR and therefore must be turned back to
         // ASCII.
         char* tmp = WideCharToAnsi(++l);
         // How do we nuke tmp so we don't get a memory leak?
         // Well, we need to teach StreamLicenseA to do that for us.
         bManageCookie = TRUE;
         es.dwCookie = (DWORD_PTR) tmp;
      }
#else
      bManageCookie = FALSE;
      es.dwCookie = (DWORD_PTR)(++l);
#endif
    }

    selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION);

    SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]);
    SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]);
    CheckDlgButton(hwndDlg,IDC_LICENSEAGREE+!selected,BST_CHECKED);
    EnableNext(selected);

    hwLicense=GetUIItem(IDC_EDIT1);
    SetActiveCtl(hwLicense);
    SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0);
#define lbg g_header->license_bg
    SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg));
#undef lbg
    SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS
    dwRead=0;
    SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l));
    SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es);
    ignoreWMCommand = 0;
    return FALSE;
  }
  if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && !ignoreWMCommand) {
    if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) {
      int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED;
      m_this_page->flags &= ~PF_LICENSE_SELECTED;
      m_this_page->flags |= is;
      EnableNext(is);
      SetNextDef();
    }
  }
  if (uMsg == WM_NOTIFY) {
    hwLicense=GetUIItem(IDC_EDIT1);
    #define nmhdr ((NMHDR *)lParam)
    #define enlink ((ENLINK *)lParam)
    #define msgfilter ((MSGFILTER *)lParam)
    if (nmhdr->code==EN_LINK) {
      if (enlink->msg==WM_LBUTTONDOWN) {
        TEXTRANGE tr = {
          {
            enlink->chrg.cpMin,
            enlink->chrg.cpMax,
          },
          ps_tmpbuf
        };
        if (tr.chrg.cpMax-tr.chrg.cpMin < sizeof(ps_tmpbuf)) {
          SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr);
          SetCursor(LoadCursor(0, IDC_WAIT));
          ShellExecute(hwndDlg,_T("open"),tr.lpstrText,NULL,NULL,SW_SHOWNORMAL);
          SetCursor(LoadCursor(0, IDC_ARROW));
        }
      }
    }
    //Ximon Eighteen 8th September 2002 Capture return key presses in the rich
    //edit control now that the control gets the focus rather than the default
    //push button. When the user presses return ask the outer dialog to move
    //the installer onto the next page. MSDN docs say return non-zero if the
    //rich edit control should NOT process this message, hence the return 1.
    //
    //This is required because the RichEdit control is eating all the key hits.
    //It does try to release some and convert VK_ESCAPE to WM_CLOSE, VK_ENTER
    //to a push on the default button and VM_TAB to WM_NEXTDLGCTL. But sadly it
    //it sends all of these messages to its parent instead of just letting the
    //dialog manager handle them. Instead of properly handling WM_GETDLGCODE,
    //it mimics the dialog manager.
    if (nmhdr->code==EN_MSGFILTER)
    {
      if (msgfilter->msg==WM_KEYDOWN)
      {
        if (msgfilter->wParam==VK_RETURN) {
          SendMessage(g_hwnd, WM_COMMAND, IDOK, 0);
        }
        if (msgfilter->wParam==VK_ESCAPE) {
          SendMessage(g_hwnd, WM_CLOSE, 0, 0);
        }
        return 1;
      }
    }
    #undef nmhdr
    #undef enlink
    #undef msgfilter
  }
  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    ignoreWMCommand++;
  }
  return HandleStaticBkColor();
}
コード例 #7
0
ファイル: Ui.c プロジェクト: kichik/nsis-1
static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static int dontsetdefstyle;
  page *thispage = g_this_page;
  char *dir = g_usrvars[thispage->parms[4]];
  int browse_text = thispage->parms[3];
  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    GetUIText(IDC_DIR,dir);
    validate_filename(dir);
#ifdef NSIS_CONFIG_LOG
#ifndef NSIS_CONFIG_LOG_ODS
    build_g_logfile();
#endif
    log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
#endif
  }
  if (uMsg == WM_INITDIALOG)
  {
#ifdef NSIS_CONFIG_LOG
    if (GetAsyncKeyState(VK_SHIFT)&0x8000)
    {
      HWND h=GetUIItem(IDC_CHECK1);
      SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS);
      ShowWindow(h,SW_SHOWNA);
    }
#endif
    if (validpathspec(dir) && !skip_root(dir))
      addtrailingslash(dir);
    SetUITextNT(IDC_DIR,dir);
    SetUITextFromLang(IDC_BROWSE,this_page->parms[2]);
    SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]);
    SetActiveCtl(hwndDlg, GetUIItem(IDC_DIR));
  }
  if (uMsg == WM_COMMAND)
  {
    int id=LOWORD(wParam);
    if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
    {
      uMsg = WM_IN_UPDATEMSG;
    }
    if (id == IDC_BROWSE)
    {
      BROWSEINFO bi = {0,};
      ITEMIDLIST *idlist;
      bi.hwndOwner = hwndDlg;
      bi.pszDisplayName = g_tmp;
      bi.lpfn = BrowseCallbackProc;
      bi.lParam = (LPARAM)dir;
      bi.lpszTitle = GetNSISStringTT(browse_text);
#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#endif
      bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
      idlist = SHBrowseForFolder(&bi);
      if (idlist)
      {
        // Get and free idlist
        my_PIDL2Path(g_tmp, idlist);

        if (g_header->install_directory_auto_append)
        {
          const char *post_str=ps_tmpbuf;
          GetNSISStringTT(g_header->install_directory_auto_append);
          // name gives just the folder name
          if (lstrcmpi(post_str,g_tmp))
          {
            lstrcat(addtrailingslash(dir),post_str);
          }
        }

        dontsetdefstyle++;
        SetUITextNT(IDC_DIR,dir);
      }
    }
  }
  if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START)
  {
    static char s[NSIS_MAX_STRLEN];
    char *p;
    int error = 0;
    int total, available=-1;
    DWORD spc,bps,fc,tc;

    GetUIText(IDC_DIR,dir);
    if (!is_valid_instpath(dir))
      error = NSIS_INSTDIR_INVALID;

    mystrcpy(s,dir);
    p=skip_root(s);
    if (p)
      *p=0;

    if (GetDiskFreeSpace(s,&spc,&bps,&fc,&tc))
    {
      DWORD r=MulDiv(bps*spc,fc,1<<10);
      if (r > 0x7fffffff) r=0x7fffffff;
      available=(int)r;
    }

    total = sumsecsfield(size_kb);

    if ((unsigned int)available < (unsigned int)total)
      error = NSIS_INSTDIR_NOT_ENOUGH_SPACE;

    if (LANG_STR_TAB(LANG_SPACE_REQ)) {
      SetUITextNT(IDC_SPACEREQUIRED,inttosizestr(total,GetNSISString(s,LANG_SPACE_REQ)));
      if (available != -1)
        SetUITextNT(IDC_SPACEAVAILABLE,inttosizestr(available,GetNSISString(s,LANG_SPACE_AVAIL)));
      else
        SetUITextNT(IDC_SPACEAVAILABLE,"");
    }

    g_exec_flags.instdir_error = error;

#ifdef NSIS_SUPPORT_CODECALLBACKS
    if (!error)
      error = ExecuteCodeSegment(g_header->code_onVerifyInstDir,NULL);
#endif

    if (thispage->flags & PF_DIR_NO_BTN_DISABLE)
      error = 0;

    EnableNext(!error);
    if (!error && !dontsetdefstyle)
      SetNextDef();
    dontsetdefstyle = 0;
  }
  return HandleStaticBkColor();
}