summaryrefslogtreecommitdiff
path: root/Rx/v2/examples/win_text
diff options
context:
space:
mode:
Diffstat (limited to 'Rx/v2/examples/win_text')
-rw-r--r--Rx/v2/examples/win_text/CMakeLists.txt54
-rw-r--r--Rx/v2/examples/win_text/main.cpp244
-rw-r--r--Rx/v2/examples/win_text/rx_windows_user.h117
-rw-r--r--Rx/v2/examples/win_text/unwinder.h54
-rw-r--r--Rx/v2/examples/win_text/windows_user.h118
5 files changed, 0 insertions, 587 deletions
diff --git a/Rx/v2/examples/win_text/CMakeLists.txt b/Rx/v2/examples/win_text/CMakeLists.txt
deleted file mode 100644
index 8aabd25..0000000
--- a/Rx/v2/examples/win_text/CMakeLists.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(SAMPLE_PROJECT "${CMAKE_CURRENT_SOURCE_DIR}" NAME)
-
-project(${SAMPLE_PROJECT})
-
-FIND_PACKAGE(Threads)
-
-MESSAGE( STATUS "CMAKE_CXX_COMPILER_ID: " ${CMAKE_CXX_COMPILER_ID} )
-if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- MESSAGE( STATUS "using clang settings" )
- add_compile_options( -Wall -Wextra -Werror )
- add_compile_options( -std=c++11 -stdlib=libc++ )
- add_compile_options( -ftemplate-depth=1024 ) # sometimes you just do what the compiler tells you
-elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
- MESSAGE( STATUS "using gnu settings" )
- add_compile_options( -Wall -Wextra -Werror )
- add_compile_options( -std=c++11 )
-elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
- MESSAGE( STATUS "using msvc settings" )
- add_compile_options( /W4 /WX )
- add_compile_options( /wd4503 ) # truncated symbol
- add_compile_options( /wd4702 ) # unreachable code
- add_compile_options( /wd4091 ) # typedef ignored on left when no variable is declared
- add_compile_options( /bigobj )
- add_definitions( /DUNICODE /D_UNICODE ) # it is a new millenium
-endif()
-
-
-# define some folders
-get_filename_component(RXCPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
-get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH)
-get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH)
-get_filename_component(RXCPP_DIR "${RXCPP_DIR}" PATH)
-
-MESSAGE( STATUS "RXCPP_DIR: " ${RXCPP_DIR} )
-
-include_directories(SYSTEM ${RXCPP_DIR}/ext/catch/include)
-include_directories(${RXCPP_DIR}/Ix/CPP/src ${RXCPP_DIR}/Rx/v2/src)
-
-# define the sources
-set(SAMPLE_SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
-)
-add_executable(${SAMPLE_PROJECT} WIN32 ${SAMPLE_SOURCES})
-TARGET_LINK_LIBRARIES(${SAMPLE_PROJECT} ${CMAKE_THREAD_LIBS_INIT})
-
-# configure unit tests via CTest
-enable_testing()
-set(CTEST_CONFIGURATION_TYPE "${JOB_BUILD_CONFIGURATION}")
-
-add_test(NAME RunTests
- WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
- COMMAND ${SAMPLE_PROJECT} ${TEST_ARGS}) \ No newline at end of file
diff --git a/Rx/v2/examples/win_text/main.cpp b/Rx/v2/examples/win_text/main.cpp
deleted file mode 100644
index 709cc2f..0000000
--- a/Rx/v2/examples/win_text/main.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-
-// win_text.cpp : Defines the entry point for the application.
-//
-//
-
-#define STRICT
-#define WIN32_LEAN_AND_MEAN
-#define NOMINMAX
-
-#include <windows.h>
-#include <windowsx.h>
-#include <ole2.h>
-#include <commctrl.h>
-#include <shlwapi.h>
-#include <shlobj.h>
-#include <shellapi.h>
-
-#pragma comment(lib, "user32.lib")
-#pragma comment(lib, "gdi32.lib")
-#pragma comment(lib, "Comctl32.lib")
-#pragma comment(lib, "Ole32.lib")
-
-#include <new>
-#include <utility>
-#include <memory>
-#include <type_traits>
-#include <tuple>
-#include <list>
-
-#include "rxcpp/rx.hpp"
-// create alias' to simplify code
-// these are owned by the user so that
-// conflicts can be managed by the user.
-namespace rx=rxcpp;
-namespace rxsub=rxcpp::subjects;
-namespace rxu=rxcpp::util;
-
-// At this time, RxCpp will fail to compile if the contents
-// of the std namespace are merged into the global namespace
-// DO NOT USE: 'using namespace std;'
-
-#include "unwinder.h"
-
-#include "windows_user.h"
-namespace wu = windows_user;
-
-#include "rx_windows_user.h"
-namespace rxwu = rxcpp::windows_user;
-
-struct RootWindow : public rxwu::rx_messages, public rxwu::enable_send_call<RootWindow, WM_USER+1>
-{
- // window class
- using window_class = wu::window_class<RootWindow>;
- static LPCWSTR class_name() {return L"Scratch";}
- static void change_class(WNDCLASSEX&) {}
-
- // createstruct parameter type
- using param_type = std::wstring;
-
- // public methods
-
- // static methods use a window message per call
-
- static LRESULT set_title(HWND w, const std::wstring& t) {
- return send_call(w, [&](RootWindow& r){
- r.set_title(t);
- return 0;
- });
- }
- static std::wstring get_title(HWND w) {
- std::wstring t;
- send_call(w, [&](RootWindow& r){
- t = r.get_title();
- return 0;
- });
- return t;
- }
-
- // instance methods are accessed using static send_call(hwnd, [](RootWindow& r){. . .});
- // send_call uses one window message, the lambda can call many instance methods.
-
- void set_title(const std::wstring& t) {
- title = t;
- }
- const std::wstring& get_title() {
- return title;
- }
-
- // lifetime
-
- // called during WM_NCDESTROY
- ~RootWindow() {
- PostQuitMessage(0);
- }
-
- // called during WM_NCCREATE
- RootWindow(HWND w, LPCREATESTRUCT, param_type* title)
- : window(w)
- , title(title ? *title : L"RootWindow")
- , position{40, 10} {
- // listen for the following messages
- OnPaint();
- OnPrintClient();
- OnKeyDown();
- OnMovesWhileLButtonDown();
- }
-
-private:
- // implementation
-
- HWND window;
- std::wstring title;
- POINTS position;
-
- void PaintContent(PAINTSTRUCT& ps) {
- RECT rect;
- GetClientRect (window, &rect) ;
- SetTextColor(ps.hdc, 0x00000000);
- SetBkMode(ps.hdc,TRANSPARENT);
- rect.left=position.x;
- rect.top=position.y;
- DrawText( ps.hdc, title.c_str(), -1, &rect, DT_SINGLELINE | DT_NOCLIP ) ;
- }
-
- void OnKeyDown() {
- messages<WM_KEYDOWN>().
- subscribe([this](auto m) {
- m.handled(); // skip DefWindowProc
-
- MessageBox(window, L"KeyDown", L"RootWindow", MB_OK);
- // NOTE: MessageBox pumps messages, but this subscription only
- // receives messages if it is suspended by 'for await', so any
- // WM_KEYDOWN arriving while the message box is up is not delivered.
- // the other subscriptions will receive messages.
- });
- }
-
- void OnMovesWhileLButtonDown() {
-
- auto moves_while_lbutton_down = messages<WM_LBUTTONDOWN>().
- map(
- [this](auto m) {
- m.handled(); // skip DefWindowProc
-
- return this->messages<WM_MOUSEMOVE>().
- take_until(this->messages<WM_LBUTTONUP>());
- }).
- merge();
-
- moves_while_lbutton_down.
- subscribe([this](auto m) {
- m.handled(); // skip DefWindowProc
-
- position = MAKEPOINTS(m.lParam);
- InvalidateRect(window, nullptr, true);
- });
- }
-
- void OnPaint() {
- messages<WM_PAINT>().
- subscribe([this](auto m) {
- m.handled(); // skip DefWindowProc
-
- PAINTSTRUCT ps;
- BeginPaint(window, &ps);
- PaintContent(ps);
- EndPaint(window, &ps);
- });
- }
-
- void OnPrintClient() {
- messages<WM_PRINTCLIENT, HDC>().
- subscribe([this](auto m) {
- m.handled(); // skip DefWindowProc
-
- PAINTSTRUCT ps;
- ps.hdc = m.wParam;
- GetClientRect(window, &ps.rcPaint);
- PaintContent(ps);
- });
- }
-};
-
-int PASCAL
-wWinMain(HINSTANCE hinst, HINSTANCE, LPWSTR, int nShowCmd)
-{
- HRESULT hr = S_OK;
-
- hr = CoInitialize(NULL);
- if (FAILED(hr))
- {
- return FALSE;
- }
- ON_UNWIND_AUTO([&]{CoUninitialize();});
-
- InitCommonControls();
-
- RootWindow::window_class::Register();
-
- LONG winerror = ERROR_SUCCESS;
-
- std::wstring title{L"Scratch App - RootWindow"};
-
- // normal create window call, just takes the class name and optional create parameters
- HWND window = CreateWindow(
- RootWindow::window_class::Name(), title.c_str(),
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL,
- hinst,
- &title);
- if (!window) {winerror = GetLastError();}
-
- if (!!winerror || !window)
- {
- return winerror;
- }
-
- ShowWindow(window, nShowCmd);
-
- // interact with window safely on the UI thread from another thread
- auto settitle = std::async([window](){
-
- // by static method (two SendMessage)
- RootWindow::set_title(window, L"SET_TITLE! " + RootWindow::get_title(window));
-
- // or multiple instance methods (one SendMessage)
- RootWindow::send_call(window, [](RootWindow& r){
- r.set_title(L"SEND_CALL! " + r.get_title());
- return 0;
- });
- });
-
- MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- settitle.get();
-
- return 0;
-}
diff --git a/Rx/v2/examples/win_text/rx_windows_user.h b/Rx/v2/examples/win_text/rx_windows_user.h
deleted file mode 100644
index 708eaf6..0000000
--- a/Rx/v2/examples/win_text/rx_windows_user.h
+++ /dev/null
@@ -1,117 +0,0 @@
-#pragma once
-
-namespace rxcpp { namespace windows_user {
-
- struct rx_messages
- {
- struct Result
- {
- LRESULT lres = 0;
- bool handled = false;
- };
-
- struct Message
- {
- template<UINT WM>
- static auto is() { return [](Message m){ return m.message == WM; }; }
-
- HWND hWnd;
- UINT message;
- WPARAM wParam;
- LPARAM lParam;
- Result* result;
-
- void handled() { result->handled = true; }
- void lresult(LRESULT lres) {result->lres = lres; }
-
- template<class T>
- T wparam_cast(){
- return *reinterpret_cast<T*>(std::addressof(wParam));
- }
-
- template<class T>
- T lparam_cast(){
- return *reinterpret_cast<T*>(std::addressof(lParam));
- }
- };
-
- template<class WPARAM_t = WPARAM, class LPARAM_t = LPARAM>
- struct TypedMessage
- {
- static auto as() { return [](Message m){return TypedMessage{m}; }; }
-
- TypedMessage(Message m)
- : hWnd(m.hWnd)
- , message(m.message)
- , wParam(m.wparam_cast<WPARAM_t>())
- , lParam(m.lparam_cast<LPARAM_t>())
- , result(m.result)
- {}
-
- HWND hWnd;
- UINT message;
- WPARAM_t wParam;
- LPARAM_t lParam;
- Result* result;
-
- void handled() { result->handled = true; }
- void lresult(LRESULT lres) {result->lres = lres; }
- };
-
- subjects::subject<Message> subject;
- subscriber<Message> sub;
-
- ~rx_messages() {
- sub.on_completed();
- }
- rx_messages() : sub(subject.get_subscriber()) {}
-
- std::tuple<bool, LRESULT> message(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
- Result result;
- auto m = Message{hWnd, message, wParam, lParam, &result};
- try {
- sub.on_next(m);
- } catch(...) {
- sub.on_error(std::current_exception());
- }
- return std::make_tuple(result.handled, result.lres);
- }
-
- observable<Message> messages() {
- return subject.get_observable();
- }
-
- template<UINT WM>
- observable<Message> messages() {
- return messages().filter(Message::is<WM>());
- }
-
- template<UINT WM, class WPARAM_t, class LPARAM_t = LPARAM>
- observable<TypedMessage<WPARAM_t, LPARAM_t>> messages() {
- return messages<WM>().map(TypedMessage<WPARAM_t, LPARAM_t>::as());
- }
-
- };
-
- template<class Derived, UINT WM>
- struct enable_send_call
- {
- static LRESULT send_call(HWND w, std::function<LRESULT(Derived&)> f) {
- auto fp = reinterpret_cast<LPARAM>(std::addressof(f));
- return SendMessage(w, WM, 0, fp);
- }
-
- void OnSendCall() {
- auto derived = static_cast<Derived*>(this);
- derived->messages<WM, WPARAM, std::function<LRESULT(Derived&)>*>().
- subscribe([=](auto m) {
- m.handled(); // skip DefWindowProc
- m.lresult((*m.lParam)(*derived));
- });
- }
-
- enable_send_call() {
- OnSendCall();
- }
- };
-} }
diff --git a/Rx/v2/examples/win_text/unwinder.h b/Rx/v2/examples/win_text/unwinder.h
deleted file mode 100644
index a01a170..0000000
--- a/Rx/v2/examples/win_text/unwinder.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#pragma once
-
-namespace unwinder { namespace detail {
-
- template<typename Function>
- class unwinder
- {
- public:
- ~unwinder() noexcept
- {
- if (!!function)
- {
- (*function)();
- }
- }
-
- explicit unwinder(Function* functionArg)
- : function(functionArg)
- {
- }
-
- void dismiss()
- {
- function = nullptr;
- }
-
- unwinder& operator=(nullptr_t) {
- dismiss();
- return *this;
- }
-
- private:
- unwinder();
- unwinder(const unwinder&);
- unwinder& operator=(const unwinder&);
-
- Function* function;
- };
-} }
-
-#define UNWIND_MAKE_IDENTIFIER_EXPLICIT_PASTER(Prefix, Suffix) Prefix ## Suffix
-#define UNWIND_MAKE_IDENTIFIER_EXPLICIT(Prefix, Suffix) UNWIND_MAKE_IDENTIFIER_EXPLICIT_PASTER(Prefix, Suffix)
-
-#define UNWIND_MAKE_IDENTIFIER(Prefix) UNWIND_MAKE_IDENTIFIER_EXPLICIT(Prefix, __LINE__)
-
-#define ON_UNWIND(Name, Function) \
- ON_UNWIND_EXPLICIT(uwfunc_ ## Name, Name, Function)
-
-#define ON_UNWIND_AUTO(Function) \
- ON_UNWIND_EXPLICIT(UNWIND_MAKE_IDENTIFIER(uwfunc_), UNWIND_MAKE_IDENTIFIER(unwind_), Function)
-
-#define ON_UNWIND_EXPLICIT(FunctionName, UnwinderName, Function) \
- auto FunctionName = (Function); \
- ::unwinder::detail::unwinder<decltype(FunctionName)> UnwinderName(std::addressof(FunctionName))
diff --git a/Rx/v2/examples/win_text/windows_user.h b/Rx/v2/examples/win_text/windows_user.h
deleted file mode 100644
index 418f73f..0000000
--- a/Rx/v2/examples/win_text/windows_user.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma once
-
-namespace windows_user {
-
- EXTERN_C IMAGE_DOS_HEADER __ImageBase;
- inline HINSTANCE GetCurrentInstance(){ return ((HINSTANCE)&__ImageBase); }
-
- template<typename Type>
- LRESULT CALLBACK WindowCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) noexcept;
-
- template<typename Type>
- class window_class
- {
- public:
- static LPCWSTR Name() {
- return Type::class_name();
- }
-
- static ATOM Register() {
- WNDCLASSEX wcex = {};
- wcex.cbSize = sizeof(WNDCLASSEX);
-
- // defaults that can be overriden
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.hInstance = GetCurrentInstance();
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcex.style = 0;
- wcex.hIcon = NULL;
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.lpszMenuName = NULL;
-
- Type::change_class(wcex);
-
- // not overridable
- wcex.lpszClassName = Name();
- wcex.lpfnWndProc = WindowCallback<Type>;
-
- return RegisterClassEx(&wcex);
- }
-
- private:
- ~window_class();
- window_class();
- window_class(window_class&);
- window_class& operator=(window_class&);
- };
-
- namespace detail {
- template<typename Type>
- std::unique_ptr<Type> find(HWND hwnd) {
- return std::unique_ptr<Type>(reinterpret_cast<Type*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)));
- }
-
- void erase(HWND hwnd) {
- SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
- }
-
- template<typename Type>
- std::unique_ptr<Type> insert(HWND hwnd, std::unique_ptr<Type> type) {
- if (!type) {
- return nullptr;
- }
-
- SetLastError(0);
-
- ON_UNWIND(unwind_userdata, [&](){erase(hwnd);});
- auto result = SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(type.get()));
-
- LONG winerror = !result ? GetLastError() : ERROR_SUCCESS;
-
- if (!!winerror || !!result) {
- return nullptr;
- }
-
- unwind_userdata.dismiss();
- return type;
- }
- }
-
- template<typename Type>
- LRESULT CALLBACK WindowCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) noexcept {
- auto type = detail::find<Type>(hWnd);
- // don't delete type
- ON_UNWIND(unwind_type, [&](){type.release();});
-
- if (message == WM_NCCREATE) {
- if (type) {
- // the slot where we would store our type instance is full. abort.
- return FALSE;
- }
- auto cs = reinterpret_cast<LPCREATESTRUCT>(lParam);
- auto param = reinterpret_cast<Type::param_type*>(cs->lpCreateParams);
- type = detail::insert(hWnd, std::unique_ptr<Type>(new (std::nothrow) Type(hWnd, cs, param)));
- if (!type) {
- return FALSE;
- }
- }
-
- LRESULT lResult = 0;
- bool handled = false;
-
- if (type) {
- std::tie(handled, lResult) = type->message(hWnd, message, wParam, lParam);
- }
-
- if (!handled) {
- lResult = DefWindowProc(hWnd, message, wParam, lParam);
- }
-
- if (message == WM_NCDESTROY) {
- detail::erase(hWnd);
- // let type destruct
- unwind_type.dismiss();
- }
-
- return lResult;
- }
-}