commit fbc834a1531360e75a985d9c532629a6cc682443
parent 3aab3df7e6d781556d94b76c47c27fbfdc99c824
Author: cfillion <cfillion@users.noreply.github.com>
Date: Sun, 31 Jan 2016 22:01:58 -0800
implement rich edit control on windows
Diffstat:
10 files changed, 193 insertions(+), 50 deletions(-)
diff --git a/src/about.cpp b/src/about.cpp
@@ -21,6 +21,7 @@
#include "index.hpp"
#include "listview.hpp"
#include "resource.hpp"
+#include "richedit.hpp"
#include "tabbar.hpp"
using namespace std;
@@ -28,11 +29,12 @@ using namespace std;
About::About(RemoteIndex *index)
: Dialog(IDD_ABOUT_DIALOG), m_index(index)
{
+ RichEdit::Init();
}
void About::onInit()
{
- m_about = getControl(IDC_ABOUT);
+ m_about = createControl<RichEdit>(IDC_ABOUT);
m_cats = createControl<ListView>(IDC_CATEGORIES, ListView::Columns{
{AUTO_STR("Category"), 140}
@@ -47,7 +49,7 @@ void About::onInit()
});
m_tabs = createControl<TabBar>(IDC_TABS, TabBar::Tabs{
- {AUTO_STR("Description"), {m_about}},
+ {AUTO_STR("Description"), {m_about->handle()}},
{AUTO_STR("Packages"), {m_cats->handle(), m_packages->handle()}},
{AUTO_STR("Installed Files"), {}},
});
@@ -74,10 +76,14 @@ void About::populate()
SetWindowText(handle(), title);
- setAboutText(
- AUTO_STR("{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\n")
- AUTO_STR("This is some {\\b bold} text.\\par\n")
- AUTO_STR("}")
+ m_about->setRichText(
+ "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1348\\cocoasubrtf170\n"
+ "{\\fonttbl\\f0\\fnil\\fcharset134 STHeitiSC-Light;}\n"
+ "{\\colortbl;\\red255\\green255\\blue255;}\n"
+ "\\margl1440\\margr1440\\vieww10800\\viewh8400\\viewkind0\n"
+ "\\pard\\tx566\\tx1133\\tx1700\\tx2267\\tx2834\\tx3401\\tx3968\\tx4535\\tx5102\\tx5669\\tx6236\\tx6803\\pardirnatural\n"
+ "\\f0\\fs24 \\cf0 http://perdu.com test"
+ "{\\field{\\*\\fldinst{HYPERLINK \"https://msdn.microsoft.com/en-us/library/windows/desktop/bb787974%28v=vs.85%29.aspx\"}}{\\fldrslt \\f0\\fs24 \\cf0 \\'d0\\'c2\\'ca\\'c0\\'bd\\'e7\\'a4\\'e8\\'a4\\'ea}}}\n"
);
m_cats->addRow({AUTO_STR("<All Categories>")});
diff --git a/src/about.hpp b/src/about.hpp
@@ -20,10 +20,9 @@
#include "dialog.hpp"
-#include "encoding.hpp"
-
class ListView;
class RemoteIndex;
+class RichEdit;
class TabBar;
class About : public Dialog {
@@ -37,12 +36,11 @@ protected:
private:
void populate();
void updatePackages(bool);
- void setAboutText(const auto_string &);
RemoteIndex *m_index;
TabBar *m_tabs;
- HWND m_about;
+ RichEdit *m_about;
ListView *m_cats;
ListView *m_packages;
};
diff --git a/src/about.mm b/src/about.mm
@@ -1,35 +0,0 @@
-/* ReaPack: Package manager for REAPER
- * Copyright (C) 2015-2016 Christian Fillion
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "about.hpp"
-
-#include <Cocoa/Cocoa.h>
-
-void About::setAboutText(const auto_string &text)
-{
- NSString *str = [NSString
- stringWithCString:text.c_str()
- encoding:NSUTF8StringEncoding
- ];
-
- NSTextView *textView = (NSTextView *)m_about;
-
- [textView
- replaceCharactersInRange: NSMakeRange(0, [[textView string] length])
- withRTF: [str dataUsingEncoding: NSUTF8StringEncoding]
- ];
-}
diff --git a/src/dialog.cpp b/src/dialog.cpp
@@ -71,7 +71,11 @@ WDL_DLGRET Dialog::Proc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam)
dlg->onContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
break;
case WM_DESTROY:
- dlg->onDestroy();
+ // On Windows, WM_DESTROY is emitted in place of WM_INITDIALOG but without
+ // our custom lParam pointer if the dialog resource is invalid
+ // (ie. because of an unloaded dll)
+ if(dlg)
+ dlg->onDestroy();
break;
};
diff --git a/src/resource.hpp b/src/resource.hpp
@@ -18,12 +18,13 @@
#ifndef REAPACK_RESOURCE_HPP
#define REAPACK_RESOURCE_HPP
-#ifndef _WIN32
+#ifdef _WIN32
+#include <commctrl.h>
+#include <richedit.h>
+#else
#define PROGRESS_CLASS "msctls_progress32"
#define WC_LISTVIEW "SysListView32"
#define WC_TABCONTROL "SysTabControl32"
-#else
-#include <commctrl.h>
#endif
#define DIALOG_STYLE \
diff --git a/src/resource.rc b/src/resource.rc
@@ -43,8 +43,13 @@ STYLE DIALOG_STYLE
FONT DIALOG_FONT
BEGIN
CONTROL "", IDC_TABS, WC_TABCONTROL, 0, 0, 2, 440, 223
+#ifdef _WIN32
+ CONTROL "", IDC_ABOUT, MSFTEDIT_CLASS, WS_VSCROLL | ES_MULTILINE |
+ ES_READONLY | NOT WS_TABSTOP, 10, 20, 420, 200
+#else
EDITTEXT IDC_ABOUT, 10, 20, 420, 200,
WS_VSCROLL | ES_MULTILINE | ES_READONLY | NOT WS_TABSTOP
+#endif
CONTROL "", IDC_CATEGORIES, WC_LISTVIEW, LVS_REPORT | LVS_SINGLESEL |
LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 10, 20, 86, 200
CONTROL "", IDC_PACKAGES, WC_LISTVIEW, LVS_REPORT | LVS_SINGLESEL |
diff --git a/src/richedit.cpp b/src/richedit.cpp
@@ -0,0 +1,85 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2016 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "richedit.hpp"
+
+#include <memory>
+
+#include "encoding.hpp"
+
+#ifdef _WIN32
+#include <richedit.h>
+#endif
+
+using namespace std;
+
+void RichEdit::Init()
+{
+#ifdef _WIN32
+ LoadLibrary(AUTO_STR("Msftedit.dll"));
+#endif
+}
+
+RichEdit::RichEdit(HWND handle)
+ : Control(handle)
+{
+#ifdef _WIN32
+ SendMessage(handle, EM_AUTOURLDETECT, true, 0);
+ SendMessage(handle, EM_SETEVENTMASK, 0, ENM_LINK);
+#endif
+}
+
+void RichEdit::onNotify(LPNMHDR info, LPARAM lParam)
+{
+#ifdef _WIN32
+ switch(info->code) {
+ case EN_LINK:
+ handleLink(lParam);
+ break;
+ };
+#endif
+}
+
+#ifdef _WIN32
+void RichEdit::handleLink(LPARAM lParam)
+{
+ ENLINK *info = (ENLINK *)lParam;
+ const CHARRANGE &range = info->chrg;
+
+ auto_char *url = new auto_char[(range.cpMax - range.cpMin) + 1]();
+ unique_ptr<auto_char[]> ptr(url);
+
+ TEXTRANGE tr{range, url};
+ SendMessage(handle(), EM_GETTEXTRANGE, 0, (LPARAM)&tr);
+
+ if(info->msg == WM_LBUTTONUP)
+ ShellExecute(nullptr, AUTO_STR("open"), url, nullptr, nullptr, SW_SHOW);
+}
+
+// OS X implementation of setRichText in richedit.mm
+void RichEdit::setRichText(const string &rtf)
+{
+ SETTEXTEX st{};
+ SendMessage(handle(), EM_SETTEXTEX, (WPARAM)&st, (LPARAM)rtf.c_str());
+
+ GETTEXTLENGTHEX tl{};
+ LONG length = (LONG)SendMessage(handle(), EM_GETTEXTLENGTHEX, (WPARAM)&tl, 0);
+
+ CHARRANGE cr{length, length};
+ SendMessage(handle(), EM_EXSETSEL, 0, (LPARAM)&cr);
+}
+#endif
diff --git a/src/richedit.hpp b/src/richedit.hpp
@@ -0,0 +1,42 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2016 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REAPACK_RICHEDIT_HPP
+#define REAPACK_RICHEDIT_HPP
+
+#include "control.hpp"
+
+#include <string>
+
+class RichEdit : public Control {
+public:
+ static void Init();
+
+ RichEdit(HWND);
+
+ void setRichText(const std::string &);
+
+protected:
+ void onNotify(LPNMHDR, LPARAM) override;
+
+private:
+#ifdef _WIN32
+ void handleLink(LPARAM);
+#endif
+};
+
+#endif
diff --git a/src/richedit.mm b/src/richedit.mm
@@ -0,0 +1,37 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2016 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "richedit.hpp"
+
+#include <Cocoa/Cocoa.h>
+
+using namespace std;
+
+void RichEdit::setRichText(const string &rtf)
+{
+ NSString *str = [NSString
+ stringWithCString:rtf.c_str()
+ encoding:NSUTF8StringEncoding
+ ];
+
+ NSTextView *textView = (NSTextView *)handle();
+
+ [textView
+ replaceCharactersInRange: NSMakeRange(0, [[textView string] length])
+ withRTF: [str dataUsingEncoding: NSUTF8StringEncoding]
+ ];
+}
diff --git a/win32.tup b/win32.tup
@@ -23,7 +23,7 @@ SQLFLAGS += /DSQLITE_OMIT_CHECK /DSQLITE_OMIT_BLOB_LITERAL
SQLFLAGS += /DSQLITE_OMIT_DECLTYPE /DSQLITE_OMIT_DEPRECATED
LD := $(WRAP) link
-LDFLAGS := /nologo user32.lib
+LDFLAGS := /nologo user32.lib shell32.lib
LDFLAGS += vendor/libcurl_@(WINARCH)/lib/libcurl_a.lib
LDFLAGS += $(TUP_VARIANTDIR)/src/resource.res
LDFLAGS += $(TUP_VARIANTDIR)/build/vendor/sqlite3.o