diff --git a/base/base.vcxproj b/base/base.vcxproj
index 54673877..ff11ae99 100644
--- a/base/base.vcxproj
+++ b/base/base.vcxproj
@@ -130,13 +130,14 @@
{8D9A6595-717A-41C8-B468-0011A72BE3D1}
Win32Proj
base
+ 10.0
StaticLibrary
true
Unicode
- v120_xp
+ v142
StaticLibrary
@@ -149,7 +150,7 @@
false
true
Unicode
- v120_xp
+ v142
StaticLibrary
@@ -204,7 +205,7 @@
Level4
Disabled
- WIN32;_DEBUG;_LIB;NOMINMAX;WITH_ENCRYPT;CURL_STATICLIB;%(PreprocessorDefinitions)
+ WIN32;_DEBUG;_LIB;NOMINMAX;CURL_STATICLIB;%(PreprocessorDefinitions)
false
.\;..\
4100;4127;4244;4245;4310;4355;4505;%(DisableSpecificWarnings)
@@ -250,7 +251,7 @@
MaxSpeed
true
true
- WIN32;NDEBUG;_LIB;NOMINMAX;WITH_ENCRYPT;CURL_STATICLIB;%(PreprocessorDefinitions)
+ WIN32;NDEBUG;_LIB;NOMINMAX;CURL_STATICLIB;%(PreprocessorDefinitions)
false
.\;..\
4100;4127;4189;4244;4245;4310;4355;4505;%(DisableSpecificWarnings)
diff --git a/base/framework/message_loop_proxy.h b/base/framework/message_loop_proxy.h
index 63f2375a..4839fb96 100644
--- a/base/framework/message_loop_proxy.h
+++ b/base/framework/message_loop_proxy.h
@@ -70,7 +70,7 @@ private:
// The lock that protects access to target_message_loop_.
mutable NLock message_loop_lock_;
- MessageLoop* target_message_loop_;
+ nbase::MessageLoop* target_message_loop_;
private:
// This relay class remembers the MessageLoop that it was created on, and
diff --git a/base/framework/win_ui_message_pump.cpp b/base/framework/win_ui_message_pump.cpp
index ccec39b3..d16543b0 100644
--- a/base/framework/win_ui_message_pump.cpp
+++ b/base/framework/win_ui_message_pump.cpp
@@ -14,396 +14,392 @@
namespace nbase
{
+ static const wchar_t kWndClass[] = L"NeteaseMessagePumpWindow";
+ static const unsigned int kMsgHaveWork = WM_USER + 1;
+ static const int kUserTimerMinmum = 10;
-static const wchar_t kWndClass[] = L"NeteaseMessagePumpWindow";
-static const unsigned int kMsgHaveWork = WM_USER + 1;
-static const int kUserTimerMinmum = 10;
-
-WinUIMessagePump::WinUIMessagePump()
-{
- InitMessageWnd();
-}
-
-WinUIMessagePump::~WinUIMessagePump()
-{
- ::DestroyWindow(message_hwnd_);
- ::UnregisterClassW(kWndClass, ::GetModuleHandle(NULL));
-}
-
-void WinUIMessagePump::ScheduleWork()
-{
- if (::InterlockedExchange(&have_work_, 1))
- return; // Pump已经开始
-
- // 通知MessagePump有新任务到达,如果MessagePump处于睡眠状态,这将唤醒它
- ::PostMessageW(message_hwnd_, kMsgHaveWork, reinterpret_cast(this), 0);
-}
-
-void WinUIMessagePump::ScheduleDelayedWork(const TimeTicks& delayed_work_time)
-{
- //
- // We would *like* to provide high resolution timers. Windows timers using
- // SetTimer() have a 10ms granularity. We have to use WM_TIMER as a wakeup
- // mechanism because the application can enter modal windows loops where it
- // is not running our MessageLoop; the only way to have our timers fire in
- // these cases is to post messages there.
- //
- // To provide sub-10ms timers, we process timers directly from our run loop.
- // For the common case, timers will be processed there as the run loop does
- // its normal work. However, we *also* set the system timer so that WM_TIMER
- // events fire. This mops up the case of timers not being able to work in
- // modal message loops. It is possible for the SetTimer to pop and have no
- // pending timers, because they could have already been processed by the
- // run loop itself.
- //
- // We use a single SetTimer corresponding to the timer that will expire
- // soonest. As new timers are created and destroyed, we update SetTimer.
- // Getting a spurrious SetTimer event firing is benign, as we'll just be
- // processing an empty timer queue.
- //
- delayed_work_time_ = delayed_work_time;
-
- DWORD wait_time;
- int64_t delay_msec = GetCurrentDelay();
- if (delay_msec < kUserTimerMinmum)
- wait_time = kUserTimerMinmum;
- else if (delay_msec < 0)
- wait_time = INFINITE;
- else if (delay_msec > 0xfffffffe)
- wait_time = 0xfffffffe;
- else
- wait_time = static_cast(delay_msec);
-
-
- // Create a WM_TIMER event that will wake us up to check for any pending
- // timers (in case we are running within a nested, external sub-pump).
- ::SetTimer(message_hwnd_, reinterpret_cast(this), wait_time, NULL);
-}
-
-void WinUIMessagePump::PumpOutPendingPaintMessages()
-{
- // If we are being called outside of the context of Run, then don't try to do
- // any work.
- if (!state_)
- return;
-
- // Create a mini-message-pump to force immediate processing of only Windows
- // WM_PAINT messages. Don't provide an infinite loop, but do enough peeking
- // to get the job done. Actual common max is 4 peeks, but we'll be a little
- // safe here.
- const int kMaxPeekCount = 20;
- int peek_count;
- for (peek_count = 0; peek_count < kMaxPeekCount; ++peek_count)
+ WinUIMessagePump::WinUIMessagePump()
{
- MSG msg;
- if (!::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE | PM_QS_PAINT))
- break;
- ProcessMessageHelper(msg);
- if (state_->should_quit) // Handle WM_QUIT.
- break;
+ InitMessageWnd();
}
-}
-void WinUIMessagePump::InitMessageWnd()
-{
- HINSTANCE hinst = ::GetModuleHandle(NULL);
-
- WNDCLASSEXW wc = {0};
- wc.cbSize = sizeof(wc);
- wc.lpfnWndProc = WndProcThunk;
- wc.hInstance = hinst;
- wc.lpszClassName = kWndClass;
- ::RegisterClassExW(&wc);
-
- message_hwnd_ = ::CreateWindowW(kWndClass, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0);
-}
-
-LRESULT CALLBACK WinUIMessagePump::WndProcThunk(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
-{
- switch (message)
+ WinUIMessagePump::~WinUIMessagePump()
{
- case kMsgHaveWork:
- reinterpret_cast(wparam)->HandleWorkMessage();
- break;
- case WM_TIMER:
- reinterpret_cast(wparam)->HandleTimerMessage();
- break;
+ ::DestroyWindow(message_hwnd_);
+ ::UnregisterClassW(kWndClass, ::GetModuleHandle(NULL));
}
- return ::DefWindowProcW(hwnd, message, wparam, lparam);
-}
-void WinUIMessagePump::DoRunLoop()
-{
- // IF this was just a simple ::PeekMessageW() loop (servicing all possible work
- // queues), then Windows would try to achieve the following order according
- // to MSDN documentation about ::PeekMessageW with no filter):
- // * Sent messages
- // * Posted messages
- // * Sent messages (again)
- // * WM_PAINT messages
- // * WM_TIMER messages
- //
- // Summary: none of the above classes is starved, and sent messages has twice
- // the chance of being processed (i.e., reduced service time).
-
- for (;;)
+ void WinUIMessagePump::ScheduleWork()
{
- // If we do any work, we may create more messages etc., and more work may
- // possibly be waiting in another task group. When we (for example)
- // ProcessNextWindowsMessage(), there is a good chance there are still more
- // messages waiting. On the other hand, when any of these methods return
- // having done no work, then it is pretty unlikely that calling them again
- // quickly will find any work to do. Finally, if they all say they had no
- // work, then it is a good time to consider sleeping (waiting) for more
- // work.
+ if (::InterlockedExchange(&have_work_, 1))
+ return; // Pump已经开始
- bool more_work_is_plausible = ProcessNextWindowsMessage();
- if (state_->should_quit)
- break;
-
- more_work_is_plausible |= state_->delegate->DoWork();
- if (state_->should_quit)
- break;
-
- more_work_is_plausible |=
- state_->delegate->DoDelayedWork(&delayed_work_time_);
- // If we did not process any delayed work, then we can assume that our
- // existing WM_TIMER if any will fire when delayed work should run. We
- // don't want to disturb that timer if it is already in flight. However,
- // if we did do all remaining delayed work, then lets kill the WM_TIMER.
- if (more_work_is_plausible && delayed_work_time_.is_null())
- KillTimer(message_hwnd_, reinterpret_cast(this));
- if (state_->should_quit)
- break;
-
- if (more_work_is_plausible)
- continue;
-
- more_work_is_plausible = state_->delegate->DoIdleWork();
- if (state_->should_quit)
- break;
-
- if (more_work_is_plausible)
- continue;
-
- WaitForWork(); // Wait (sleep) until we have work to do again.
+ // 通知MessagePump有新任务到达,如果MessagePump处于睡眠状态,这将唤醒它
+ ::PostMessageW(message_hwnd_, kMsgHaveWork, reinterpret_cast(this), 0);
}
-}
-void WinUIMessagePump::WaitForWork()
-{
- // Wait until a message is available, up to the time needed by the timer
- // manager to fire the next set of timers.
- int64_t delay = GetCurrentDelay();
- DWORD wait_time;
- if (delay < 0) // Negative value means no timers waiting.
- wait_time = INFINITE;
- else if (delay > 0xfffffffe)
- wait_time = 0xfffffffe;
- else
- wait_time = static_cast(delay);
-
- DWORD result = ::MsgWaitForMultipleObjectsEx(0, NULL, wait_time, QS_ALLINPUT, MWMO_INPUTAVAILABLE);
-
- if (WAIT_OBJECT_0 == result)
+ void WinUIMessagePump::ScheduleDelayedWork(const TimeTicks& delayed_work_time)
{
- // A WM_* message is available.
- // If a parent child relationship exists between windows across threads
- // then their thread inputs are implicitly attached.
- // This causes the MsgWaitForMultipleObjectsEx API to return indicating
- // that messages are ready for processing (specifically mouse messages
- // intended for the child window. Occurs if the child window has capture)
- // The subsequent PeekMessages call fails to return any messages thus
- // causing us to enter a tight loop at times.
- // The WaitMessage call below is a workaround to give the child window
- // sometime to process its input messages.
- MSG msg = {0};
- DWORD queue_status = ::GetQueueStatus(QS_MOUSE);
- if (HIWORD(queue_status) & QS_MOUSE && !::PeekMessageW(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE))
+ //
+ // We would *like* to provide high resolution timers. Windows timers using
+ // SetTimer() have a 10ms granularity. We have to use WM_TIMER as a wakeup
+ // mechanism because the application can enter modal windows loops where it
+ // is not running our MessageLoop; the only way to have our timers fire in
+ // these cases is to post messages there.
+ //
+ // To provide sub-10ms timers, we process timers directly from our run loop.
+ // For the common case, timers will be processed there as the run loop does
+ // its normal work. However, we *also* set the system timer so that WM_TIMER
+ // events fire. This mops up the case of timers not being able to work in
+ // modal message loops. It is possible for the SetTimer to pop and have no
+ // pending timers, because they could have already been processed by the
+ // run loop itself.
+ //
+ // We use a single SetTimer corresponding to the timer that will expire
+ // soonest. As new timers are created and destroyed, we update SetTimer.
+ // Getting a spurrious SetTimer event firing is benign, as we'll just be
+ // processing an empty timer queue.
+ //
+ delayed_work_time_ = delayed_work_time;
+
+ DWORD wait_time;
+ int64_t delay_msec = GetCurrentDelay();
+ if (delay_msec < kUserTimerMinmum)
+ wait_time = kUserTimerMinmum;
+ else if (delay_msec < 0)
+ wait_time = INFINITE;
+ else if (delay_msec > 0xfffffffe)
+ wait_time = 0xfffffffe;
+ else
+ wait_time = static_cast(delay_msec);
+
+ // Create a WM_TIMER event that will wake us up to check for any pending
+ // timers (in case we are running within a nested, external sub-pump).
+ ::SetTimer(message_hwnd_, reinterpret_cast(this), wait_time, NULL);
+ }
+
+ void WinUIMessagePump::PumpOutPendingPaintMessages()
+ {
+ // If we are being called outside of the context of Run, then don't try to do
+ // any work.
+ if (!state_)
+ return;
+
+ // Create a mini-message-pump to force immediate processing of only Windows
+ // WM_PAINT messages. Don't provide an infinite loop, but do enough peeking
+ // to get the job done. Actual common max is 4 peeks, but we'll be a little
+ // safe here.
+ const int kMaxPeekCount = 20;
+ int peek_count;
+ for (peek_count = 0; peek_count < kMaxPeekCount; ++peek_count)
{
- WaitMessage();
+ MSG msg;
+ if (!::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE | PM_QS_PAINT))
+ break;
+ ProcessMessageHelper(msg);
+ if (state_->should_quit) // Handle WM_QUIT.
+ break;
}
- return;
- }
-}
-
-void WinUIMessagePump::HandleWorkMessage()
-{
- // If we are being called outside of the context of Run, then don't try to do
- // any work. This could correspond to a MessageBox call or something of that
- // sort.
- if (!state_)
- {
- // Since we handled a kMsgHaveWork message, we must still update this flag.
- ::InterlockedExchange(&have_work_, 0);
- return;
}
- // Let whatever would have run had we not been putting messages in the queue
- // run now. This is an attempt to make our dummy message not starve other
- // messages that may be in the Windows message queue.
- ProcessPumpReplacementMessage();
-
- // Now give the delegate a chance to do some work. He'll let us know if he
- // needs to do more work.
- if (state_->delegate->DoWork())
- ScheduleWork();
-}
-
-void WinUIMessagePump::HandleTimerMessage()
-{
- ::KillTimer(message_hwnd_, reinterpret_cast(this));
-
- // If we are being called outside of the context of Run, then don't do
- // anything. This could correspond to a MessageBox call or something of
- // that sort.
- if (!state_)
- return;
-
- state_->delegate->DoDelayedWork(&delayed_work_time_);
- if (!delayed_work_time_.is_null())
+ void WinUIMessagePump::InitMessageWnd()
{
- // A bit gratuitous to set delayed_work_time_ again, but oh well.
- ScheduleDelayedWork(delayed_work_time_);
- }
-}
+ HINSTANCE hinst = ::GetModuleHandle(NULL);
-bool WinUIMessagePump::ProcessNextWindowsMessage()
-{
- // If there are sent messages in the queue then PeekMessage internally
- // dispatches the message and returns false. We return true in this
- // case to ensure that the message loop peeks again instead of calling
- // MsgWaitForMultipleObjectsEx again.
- bool sent_messages_in_queue = false;
- DWORD queue_status = ::GetQueueStatus(QS_SENDMESSAGE);
- if (HIWORD(queue_status) & QS_SENDMESSAGE)
- sent_messages_in_queue = true;
+ WNDCLASSEXW wc = { 0 };
+ wc.cbSize = sizeof(wc);
+ wc.lpfnWndProc = WndProcThunk;
+ wc.hInstance = hinst;
+ wc.lpszClassName = kWndClass;
+ ::RegisterClassExW(&wc);
- MSG msg;
- if (::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
- return ProcessMessageHelper(msg);
-
- return sent_messages_in_queue;
-}
-
-bool WinUIMessagePump::ProcessMessageHelper(const MSG& msg)
-{
- if (WM_QUIT == msg.message)
- {
- // Repost the QUIT message so that it will be retrieved by the primary
- // GetMessage() loop.
- state_->should_quit = true;
- ::PostQuitMessage(static_cast(msg.wParam));
- return false;
+ message_hwnd_ = ::CreateWindowW(kWndClass, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0);
}
- // While running our main message pump, we discard kMsgHaveWork messages.
- if (msg.message == kMsgHaveWork && msg.hwnd == message_hwnd_)
- return ProcessPumpReplacementMessage();
-
- if (::CallMsgFilter(const_cast(&msg), kMessageFilterCode))
- return true;
-
- PreProcessMessage(msg);
-
- if (state_->dispatcher)
+ LRESULT CALLBACK WinUIMessagePump::WndProcThunk(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
- if (!state_->dispatcher->Dispatch(msg))
+ switch (message)
+ {
+ case kMsgHaveWork:
+ reinterpret_cast(wparam)->HandleWorkMessage();
+ break;
+ case WM_TIMER:
+ reinterpret_cast(wparam)->HandleTimerMessage();
+ break;
+ }
+ return ::DefWindowProcW(hwnd, message, wparam, lparam);
+ }
+
+ void WinUIMessagePump::DoRunLoop()
+ {
+ // IF this was just a simple ::PeekMessageW() loop (servicing all possible work
+ // queues), then Windows would try to achieve the following order according
+ // to MSDN documentation about ::PeekMessageW with no filter):
+ // * Sent messages
+ // * Posted messages
+ // * Sent messages (again)
+ // * WM_PAINT messages
+ // * WM_TIMER messages
+ //
+ // Summary: none of the above classes is starved, and sent messages has twice
+ // the chance of being processed (i.e., reduced service time).
+
+ for (;;)
+ {
+ // If we do any work, we may create more messages etc., and more work may
+ // possibly be waiting in another task group. When we (for example)
+ // ProcessNextWindowsMessage(), there is a good chance there are still more
+ // messages waiting. On the other hand, when any of these methods return
+ // having done no work, then it is pretty unlikely that calling them again
+ // quickly will find any work to do. Finally, if they all say they had no
+ // work, then it is a good time to consider sleeping (waiting) for more
+ // work.
+
+ bool more_work_is_plausible = ProcessNextWindowsMessage();
+ if (state_->should_quit)
+ break;
+
+ more_work_is_plausible |= state_->delegate->DoWork();
+ if (state_->should_quit)
+ break;
+
+ more_work_is_plausible |=
+ state_->delegate->DoDelayedWork(&delayed_work_time_);
+ // If we did not process any delayed work, then we can assume that our
+ // existing WM_TIMER if any will fire when delayed work should run. We
+ // don't want to disturb that timer if it is already in flight. However,
+ // if we did do all remaining delayed work, then lets kill the WM_TIMER.
+ if (more_work_is_plausible && delayed_work_time_.is_null())
+ KillTimer(message_hwnd_, reinterpret_cast(this));
+ if (state_->should_quit)
+ break;
+
+ if (more_work_is_plausible)
+ continue;
+
+ more_work_is_plausible = state_->delegate->DoIdleWork();
+ if (state_->should_quit)
+ break;
+
+ if (more_work_is_plausible)
+ continue;
+
+ WaitForWork(); // Wait (sleep) until we have work to do again.
+ }
+ }
+
+ void WinUIMessagePump::WaitForWork()
+ {
+ // Wait until a message is available, up to the time needed by the timer
+ // manager to fire the next set of timers.
+ int64_t delay = GetCurrentDelay();
+ DWORD wait_time;
+ if (delay < 0) // Negative value means no timers waiting.
+ wait_time = INFINITE;
+ else if (delay > 0xfffffffe)
+ wait_time = 0xfffffffe;
+ else
+ wait_time = static_cast(delay);
+
+ DWORD result = ::MsgWaitForMultipleObjectsEx(0, NULL, wait_time, QS_ALLINPUT, MWMO_INPUTAVAILABLE);
+
+ if (WAIT_OBJECT_0 == result)
+ {
+ // A WM_* message is available.
+ // If a parent child relationship exists between windows across threads
+ // then their thread inputs are implicitly attached.
+ // This causes the MsgWaitForMultipleObjectsEx API to return indicating
+ // that messages are ready for processing (specifically mouse messages
+ // intended for the child window. Occurs if the child window has capture)
+ // The subsequent PeekMessages call fails to return any messages thus
+ // causing us to enter a tight loop at times.
+ // The WaitMessage call below is a workaround to give the child window
+ // sometime to process its input messages.
+ MSG msg = { 0 };
+ DWORD queue_status = ::GetQueueStatus(QS_MOUSE);
+ if (HIWORD(queue_status) & QS_MOUSE && !::PeekMessageW(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE))
+ {
+ WaitMessage();
+ }
+ return;
+ }
+ }
+
+ void WinUIMessagePump::HandleWorkMessage()
+ {
+ // If we are being called outside of the context of Run, then don't try to do
+ // any work. This could correspond to a MessageBox call or something of that
+ // sort.
+ if (!state_)
+ {
+ // Since we handled a kMsgHaveWork message, we must still update this flag.
+ ::InterlockedExchange(&have_work_, 0);
+ return;
+ }
+
+ // Let whatever would have run had we not been putting messages in the queue
+ // run now. This is an attempt to make our dummy message not starve other
+ // messages that may be in the Windows message queue.
+ ProcessPumpReplacementMessage();
+
+ // Now give the delegate a chance to do some work. He'll let us know if he
+ // needs to do more work.
+ if (state_->delegate->DoWork())
+ ScheduleWork();
+ }
+
+ void WinUIMessagePump::HandleTimerMessage()
+ {
+ ::KillTimer(message_hwnd_, reinterpret_cast(this));
+
+ // If we are being called outside of the context of Run, then don't do
+ // anything. This could correspond to a MessageBox call or something of
+ // that sort.
+ if (!state_)
+ return;
+
+ state_->delegate->DoDelayedWork(&delayed_work_time_);
+ if (!delayed_work_time_.is_null())
+ {
+ // A bit gratuitous to set delayed_work_time_ again, but oh well.
+ ScheduleDelayedWork(delayed_work_time_);
+ }
+ }
+
+ bool WinUIMessagePump::ProcessNextWindowsMessage()
+ {
+ // If there are sent messages in the queue then PeekMessage internally
+ // dispatches the message and returns false. We return true in this
+ // case to ensure that the message loop peeks again instead of calling
+ // MsgWaitForMultipleObjectsEx again.
+ bool sent_messages_in_queue = false;
+ DWORD queue_status = ::GetQueueStatus(QS_SENDMESSAGE);
+ if (HIWORD(queue_status) & QS_SENDMESSAGE)
+ sent_messages_in_queue = true;
+
+ MSG msg;
+ if (::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
+ return ProcessMessageHelper(msg);
+
+ return sent_messages_in_queue;
+ }
+
+ bool WinUIMessagePump::ProcessMessageHelper(const MSG& msg)
+ {
+ if (WM_QUIT == msg.message)
+ {
+ // Repost the QUIT message so that it will be retrieved by the primary
+ // GetMessage() loop.
state_->should_quit = true;
+ ::PostQuitMessage(static_cast(msg.wParam));
+ return false;
+ }
+
+ // While running our main message pump, we discard kMsgHaveWork messages.
+ if (msg.message == kMsgHaveWork && msg.hwnd == message_hwnd_)
+ return ProcessPumpReplacementMessage();
+
+ if (::CallMsgFilter(const_cast(&msg), kMessageFilterCode))
+ return true;
+
+ PreProcessMessage(msg);
+
+ if (state_->dispatcher)
+ {
+ if (!state_->dispatcher->Dispatch(msg))
+ state_->should_quit = true;
+ }
+ else
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ PostProcessMessage(msg);
+
+ return true;
}
- else
+
+ bool WinUIMessagePump::ProcessPumpReplacementMessage()
{
- TranslateMessage(&msg);
- DispatchMessage(&msg);
+ // When we encounter a kMsgHaveWork message, this method is called to peek
+ // and process a replacement message, such as a WM_PAINT or WM_TIMER. The
+ // goal is to make the kMsgHaveWork as non-intrusive as possible, even though
+ // a continuous stream of such messages are posted. This method carefully
+ // peeks a message while there is no chance for a kMsgHaveWork to be pending,
+ // then resets the have_work_ flag (allowing a replacement kMsgHaveWork to
+ // possibly be posted), and finally dispatches that peeked replacement. Note
+ // that the re-post of kMsgHaveWork may be asynchronous to this thread!!
+
+ bool have_message = false;
+ MSG msg;
+ // We should not process all window messages if we are in the context of an
+ // OS modal loop, i.e. in the context of a windows API call like MessageBox.
+ // This is to ensure that these messages are peeked out by the OS modal loop.
+ if (MessageLoop::current()->os_modal_loop())
+ {
+ // We only peek out WM_PAINT and WM_TIMER here for reasons mentioned above.
+ have_message = ::PeekMessageW(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE) ||
+ ::PeekMessageW(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE);
+ }
+ else
+ {
+ have_message = (0 != ::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE));
+ }
+
+ // Since we discarded a kMsgHaveWork message, we must update the flag.
+ ::InterlockedExchange(&have_work_, 0);
+
+ // We don't need a special time slice if we didn't have_message to process.
+ if (!have_message)
+ return false;
+
+ // Guarantee we'll get another time slice in the case where we go into native
+ // windows code. This ScheduleWork() may hurt performance a tiny bit when
+ // tasks appear very infrequently, but when the event queue is busy, the
+ // kMsgHaveWork events get (percentage wise) rarer and rarer.
+ ScheduleWork();
+
+ return ProcessMessageHelper(msg);
}
- PostProcessMessage(msg);
-
- return true;
-}
-
-bool WinUIMessagePump::ProcessPumpReplacementMessage()
-{
- // When we encounter a kMsgHaveWork message, this method is called to peek
- // and process a replacement message, such as a WM_PAINT or WM_TIMER. The
- // goal is to make the kMsgHaveWork as non-intrusive as possible, even though
- // a continuous stream of such messages are posted. This method carefully
- // peeks a message while there is no chance for a kMsgHaveWork to be pending,
- // then resets the have_work_ flag (allowing a replacement kMsgHaveWork to
- // possibly be posted), and finally dispatches that peeked replacement. Note
- // that the re-post of kMsgHaveWork may be asynchronous to this thread!!
-
- bool have_message = false;
- MSG msg;
- // We should not process all window messages if we are in the context of an
- // OS modal loop, i.e. in the context of a windows API call like MessageBox.
- // This is to ensure that these messages are peeked out by the OS modal loop.
- if (MessageLoop::current()->os_modal_loop())
+ void WinUIMessagePump::AddObserver(UIObserver* observer)
{
- // We only peek out WM_PAINT and WM_TIMER here for reasons mentioned above.
- have_message = ::PeekMessageW(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE) ||
- ::PeekMessageW(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE);
+ observers_.AddObserver(observer);
}
- else
+
+ void WinUIMessagePump::RemoveObserver(UIObserver* observer)
{
- have_message = (0 != ::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE));
+ observers_.RemoveObserver(observer);
}
- // Since we discarded a kMsgHaveWork message, we must update the flag.
- ::InterlockedExchange(&have_work_, 0);
-
- // We don't need a special time slice if we didn't have_message to process.
- if (!have_message)
- return false;
-
- // Guarantee we'll get another time slice in the case where we go into native
- // windows code. This ScheduleWork() may hurt performance a tiny bit when
- // tasks appear very infrequently, but when the event queue is busy, the
- // kMsgHaveWork events get (percentage wise) rarer and rarer.
- ScheduleWork();
-
- return ProcessMessageHelper(msg);
-}
-
-void WinUIMessagePump::AddObserver(UIObserver *observer)
-{
- observers_.AddObserver(observer);
-}
-
-void WinUIMessagePump::RemoveObserver(UIObserver *observer)
-{
- observers_.RemoveObserver(observer);
-}
-
-void WinUIMessagePump::PreProcessMessage(const MSG& msg)
-{
- AutoLazyEraser lazy_eraser(&observers_);
- size_t index = 0;
- UIObserver* observer;
- while (index < observers_.GetObserverCount())
+ void WinUIMessagePump::PreProcessMessage(const MSG& msg)
{
- observer = observers_.GetObserver(index++);
- if (observer == NULL)
- continue;
- observer->PreProcessMessage(msg);
+ AutoLazyEraser lazy_eraser(&observers_);
+ size_t index = 0;
+ UIObserver* observer;
+ while (index < observers_.GetObserverCount())
+ {
+ observer = observers_.GetObserver(index++);
+ if (observer == NULL)
+ continue;
+ observer->PreProcessMessage(msg);
+ }
}
-}
-void WinUIMessagePump::PostProcessMessage(const MSG& msg)
-{
- AutoLazyEraser lazy_eraser(&observers_);
- size_t index = 0;
- UIObserver* observer;
- while (index < observers_.GetObserverCount())
+ void WinUIMessagePump::PostProcessMessage(const MSG& msg)
{
- observer = observers_.GetObserver(index++);
- if (observer == NULL)
- continue;
- observer->PostProcessMessage(msg);
+ AutoLazyEraser lazy_eraser(&observers_);
+ size_t index = 0;
+ UIObserver* observer;
+ while (index < observers_.GetObserverCount())
+ {
+ observer = observers_.GetObserver(index++);
+ if (observer == NULL)
+ continue;
+ observer->PostProcessMessage(msg);
+ }
}
-}
-
} // namespace nbase
-#endif // OS_WIN
-
+#endif // OS_WIN
\ No newline at end of file
diff --git a/bin/resources/themes/default/basic/basic.xml b/bin/resources/themes/default/basic/basic.xml
index 0ecbb7da..e035af39 100644
--- a/bin/resources/themes/default/basic/basic.xml
+++ b/bin/resources/themes/default/basic/basic.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/bin/resources/themes/default/richlist/item.xml b/bin/resources/themes/default/richlist/item.xml
index 2fb0af60..bcee60d5 100644
--- a/bin/resources/themes/default/richlist/item.xml
+++ b/bin/resources/themes/default/richlist/item.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/bin/resources/themes/default/virtualbox/main.xml b/bin/resources/themes/default/virtualbox/main.xml
index 92c4c28b..17170e12 100644
--- a/bin/resources/themes/default/virtualbox/main.xml
+++ b/bin/resources/themes/default/virtualbox/main.xml
@@ -1,88 +1,75 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/duilib/Utils/WinImplBase.cpp b/duilib/Utils/WinImplBase.cpp
index 8c0bd562..122b1f50 100644
--- a/duilib/Utils/WinImplBase.cpp
+++ b/duilib/Utils/WinImplBase.cpp
@@ -2,488 +2,481 @@
namespace ui
{
-
-WindowImplBase::WindowImplBase()
-{
-
-}
-
-
-WindowImplBase::~WindowImplBase()
-{
-
-}
-
-void WindowImplBase::OnFinalMessage( HWND hWnd )
-{
- __super::OnFinalMessage(hWnd);
- ReapObjects(GetRoot());
- delete this;
-}
-
-LONG WindowImplBase::GetStyle()
-{
- LONG styleValue = ::GetWindowLong(GetHWND(), GWL_STYLE);
- styleValue &= ~WS_CAPTION;
-
- return styleValue;
-}
-
-UINT WindowImplBase::GetClassStyle() const
-{
- return CS_DBLCLKS;
-}
-
-std::wstring WindowImplBase::GetResourceID() const
-{
- return _T("");
-}
-
-Control* WindowImplBase::CreateControl(const std::wstring& pstrClass)
-{
- return NULL;
-}
-
-LRESULT WindowImplBase::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- return FALSE;
-}
-
-LRESULT WindowImplBase::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- bHandled = FALSE;
- return 0;
-}
-
-LRESULT WindowImplBase::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- bHandled = FALSE;
- return 0;
-}
-
-LRESULT WindowImplBase::OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- if( ::IsIconic(GetHWND()) ) bHandled = FALSE;
- return (wParam == 0) ? TRUE : FALSE;
-}
-
-LRESULT WindowImplBase::OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- return 0;
-}
-
-LRESULT WindowImplBase::OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- bHandled = FALSE;
- if (IsZoomed(m_hWnd))
+ WindowImplBase::WindowImplBase()
{
- LPWINDOWPOS lpPos = (LPWINDOWPOS)lParam;
- if (lpPos->flags & SWP_FRAMECHANGED) // 第一次最大化,而不是最大化之后所触发的WINDOWPOSCHANGE
+ }
+
+ WindowImplBase::~WindowImplBase()
+ {
+ }
+
+ void WindowImplBase::OnFinalMessage(HWND hWnd)
+ {
+ __super::OnFinalMessage(hWnd);
+ ReapObjects(GetRoot());
+ delete this;
+ }
+
+ LONG WindowImplBase::GetStyle()
+ {
+ LONG styleValue = ::GetWindowLong(GetHWND(), GWL_STYLE);
+ styleValue &= ~WS_CAPTION;
+
+ return styleValue;
+ }
+
+ UINT WindowImplBase::GetClassStyle() const
+ {
+ return CS_DBLCLKS;
+ }
+
+ std::wstring WindowImplBase::GetResourceID() const
+ {
+ return _T("");
+ }
+
+ Control* WindowImplBase::CreateControl(const std::wstring& pstrClass)
+ {
+ return NULL;
+ }
+
+ LRESULT WindowImplBase::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ return FALSE;
+ }
+
+ LRESULT WindowImplBase::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ bHandled = FALSE;
+ return 0;
+ }
+
+ LRESULT WindowImplBase::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ bHandled = FALSE;
+ return 0;
+ }
+
+ LRESULT WindowImplBase::OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ if (::IsIconic(GetHWND())) bHandled = FALSE;
+ return (wParam == 0) ? TRUE : FALSE;
+ }
+
+ LRESULT WindowImplBase::OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ return 0;
+ }
+
+ LRESULT WindowImplBase::OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ bHandled = FALSE;
+ if (IsZoomed(m_hWnd))
{
- POINT pt = { 0, 0 };
- HMONITOR hMontorPrimary = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
- HMONITOR hMonitorTo = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
-
- if (hMonitorTo != hMontorPrimary)
+ LPWINDOWPOS lpPos = (LPWINDOWPOS)lParam;
+ if (lpPos->flags & SWP_FRAMECHANGED) // 第一次最大化,而不是最大化之后所触发的WINDOWPOSCHANGE
{
- // 解决无边框窗口在双屏下面(副屏分辨率大于主屏)时,最大化不正确的问题
- MONITORINFO miTo = { sizeof(miTo), 0 };
- GetMonitorInfo(hMonitorTo, &miTo);
+ POINT pt = { 0, 0 };
+ HMONITOR hMontorPrimary = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
+ HMONITOR hMonitorTo = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
- lpPos->x = miTo.rcWork.left;
- lpPos->y = miTo.rcWork.top;
- lpPos->cx = miTo.rcWork.right - miTo.rcWork.left;
- lpPos->cy = miTo.rcWork.bottom - miTo.rcWork.top;
+ if (hMonitorTo != hMontorPrimary)
+ {
+ // 解决无边框窗口在双屏下面(副屏分辨率大于主屏)时,最大化不正确的问题
+ MONITORINFO miTo = { sizeof(miTo), 0 };
+ GetMonitorInfo(hMonitorTo, &miTo);
+
+ lpPos->x = miTo.rcWork.left;
+ lpPos->y = miTo.rcWork.top;
+ lpPos->cx = miTo.rcWork.right - miTo.rcWork.left;
+ lpPos->cy = miTo.rcWork.bottom - miTo.rcWork.top;
+ }
}
}
+ return 0;
}
- return 0;
-}
-LRESULT WindowImplBase::OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- return 0;
-}
-
-LRESULT WindowImplBase::OnNcLButtonDbClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- /*if (!::IsZoomed(GetHWND()))
+ LRESULT WindowImplBase::OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+ return 0;
}
- else
+
+ LRESULT WindowImplBase::OnNcLButtonDbClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
- SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
- }*/
-
- return 0;
-}
-
-LRESULT WindowImplBase::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
- POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
- ::ScreenToClient(GetHWND(), &pt);
-
- UiRect rcClient;
- ::GetClientRect(GetHWND(), &rcClient);
-
- rcClient.Deflate(m_shadow.GetShadowCorner());
-
- if( !::IsZoomed(GetHWND()) ) {
- UiRect rcSizeBox = GetSizeBox();
- if( pt.y < rcClient.top + rcSizeBox.top ) {
- if (pt.y >= rcClient.top) {
- if (pt.x < (rcClient.left + rcSizeBox.left) && pt.x >= rcClient.left) return HTTOPLEFT;
- else if (pt.x >(rcClient.right - rcSizeBox.right) && pt.x <= rcClient.right) return HTTOPRIGHT;
- else return HTTOP;
- }
- else return HTCLIENT;
- }
- else if( pt.y > rcClient.bottom - rcSizeBox.bottom ) {
- if (pt.y <= rcClient.bottom) {
- if (pt.x < (rcClient.left + rcSizeBox.left) && pt.x >= rcClient.left) return HTBOTTOMLEFT;
- else if (pt.x > (rcClient.right - rcSizeBox.right) && pt.x <= rcClient.right) return HTBOTTOMRIGHT;
- else return HTBOTTOM;
- }
- else return HTCLIENT;
+ /*if (!::IsZoomed(GetHWND()))
+ {
+ SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
}
+ else
+ {
+ SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
+ }*/
- if (pt.x < rcClient.left + rcSizeBox.left) {
- if (pt.x >= rcClient.left) return HTLEFT;
- else return HTCLIENT;
- }
- if (pt.x > rcClient.right - rcSizeBox.right) {
- if (pt.x <= rcClient.right) return HTRIGHT;
- else return HTCLIENT;
- }
+ return 0;
}
- UiRect rcCaption = GetCaptionRect();
- if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
- && pt.y >= rcClient.top + rcCaption.top && pt.y < rcClient.top + rcCaption.bottom ) {
+ LRESULT WindowImplBase::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+ {
+ POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
+ ::ScreenToClient(GetHWND(), &pt);
+
+ UiRect rcClient;
+ ::GetClientRect(GetHWND(), &rcClient);
+
+ rcClient.Deflate(m_shadow.GetShadowCorner());
+
+ if (!::IsZoomed(GetHWND())) {
+ UiRect rcSizeBox = GetSizeBox();
+ if (pt.y < rcClient.top + rcSizeBox.top) {
+ if (pt.y >= rcClient.top) {
+ if (pt.x < (rcClient.left + rcSizeBox.left) && pt.x >= rcClient.left) return HTTOPLEFT;
+ else if (pt.x > (rcClient.right - rcSizeBox.right) && pt.x <= rcClient.right) return HTTOPRIGHT;
+ else return HTTOP;
+ }
+ else return HTCLIENT;
+ }
+ else if (pt.y > rcClient.bottom - rcSizeBox.bottom) {
+ if (pt.y <= rcClient.bottom) {
+ if (pt.x < (rcClient.left + rcSizeBox.left) && pt.x >= rcClient.left) return HTBOTTOMLEFT;
+ else if (pt.x > (rcClient.right - rcSizeBox.right) && pt.x <= rcClient.right) return HTBOTTOMRIGHT;
+ else return HTBOTTOM;
+ }
+ else return HTCLIENT;
+ }
+
+ if (pt.x < rcClient.left + rcSizeBox.left) {
+ if (pt.x >= rcClient.left) return HTLEFT;
+ else return HTCLIENT;
+ }
+ if (pt.x > rcClient.right - rcSizeBox.right) {
+ if (pt.x <= rcClient.right) return HTRIGHT;
+ else return HTCLIENT;
+ }
+ }
+
+ UiRect rcCaption = GetCaptionRect();
+ if (pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
+ && pt.y >= rcClient.top + rcCaption.top && pt.y < rcClient.top + rcCaption.bottom) {
Control* pControl = FindControl(pt);
- if( pControl ) {
+ if (pControl) {
if (dynamic_cast
Application
true
- v120_xp
+ v142
Unicode
@@ -42,7 +42,7 @@
Application
true
- v120_xp
+ v142
Unicode
@@ -107,7 +107,7 @@
Level3
Disabled
true
- WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
true
MultiThreadedDebug
diff --git a/examples/basic/basic_form.cpp b/examples/basic/basic_form.cpp
index bcab09ee..6b6e8a7b 100644
--- a/examples/basic/basic_form.cpp
+++ b/examples/basic/basic_form.cpp
@@ -7,7 +7,6 @@ BasicForm::BasicForm()
{
}
-
BasicForm::~BasicForm()
{
}
@@ -27,13 +26,17 @@ std::wstring BasicForm::GetWindowClassName() const
return kClassName;
}
+LRESULT BasicForm::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ return WindowImplBase::OnNcHitTest(uMsg, wParam, lParam, bHandled);
+}
+
void BasicForm::InitWindow()
{
-
}
LRESULT BasicForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
PostQuitMessage(0L);
return __super::OnClose(uMsg, wParam, lParam, bHandled);
-}
+}
\ No newline at end of file
diff --git a/examples/basic/basic_form.h b/examples/basic/basic_form.h
index ecff8cec..1f6a063e 100644
--- a/examples/basic/basic_form.h
+++ b/examples/basic/basic_form.h
@@ -15,6 +15,7 @@ public:
virtual std::wstring GetSkinFolder() override;
virtual std::wstring GetSkinFile() override;
virtual std::wstring GetWindowClassName() const override;
+ virtual LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
/**
* 收到 WM_CREATE 消息时该函数会被调用,通常做一些控件初始化的操作
@@ -28,4 +29,3 @@ public:
static const std::wstring kClassName;
};
-
diff --git a/examples/basic/main.cpp b/examples/basic/main.cpp
index 2eddd81c..added98b 100644
--- a/examples/basic/main.cpp
+++ b/examples/basic/main.cpp
@@ -11,10 +11,13 @@ enum ThreadId
};
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
- _In_opt_ HINSTANCE hPrevInstance,
- _In_ LPWSTR lpCmdLine,
- _In_ int nCmdShow)
+ _In_opt_ HINSTANCE hPrevInstance,
+ _In_ LPWSTR lpCmdLine,
+ _In_ int nCmdShow)
{
+ AllocConsole();
+ freopen("CONOUT$", "w", stdout);
+
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
@@ -40,12 +43,13 @@ void MainThread::Init()
// 濡傞渶淇敼璇锋寚瀹 Startup 鏈鍚庝袱涓弬鏁
ui::GlobalManager::Startup(theme_dir + L"resources\\", ui::CreateControlCallback(), false);
#else
+
// Release 妯″紡涓嬩娇鐢ㄨ祫婧愪腑鐨勫帇缂╁寘浣滀负璧勬簮
// 璧勬簮琚鍏ュ埌璧勬簮鍒楄〃鍒嗙被涓 THEME锛岃祫婧愬悕绉颁负 IDR_THEME
// 濡傛灉璧勬簮浣跨敤鐨勬槸鏈湴鐨 zip 鏂囦欢鑰岄潪璧勬簮涓殑 zip 鍘嬬缉鍖
// 鍙互浣跨敤 OpenResZip 鍙︿竴涓噸杞藉嚱鏁版墦寮鏈湴鐨勮祫婧愬帇缂╁寘
- ui::GlobalManager::OpenResZip(MAKEINTRESOURCE(IDR_THEME), L"THEME", "");
- // ui::GlobalManager::OpenResZip(L"resources.zip", "");
+ //ui::GlobalManager::OpenResZip(MAKEINTRESOURCE(IDR_THEME), L"THEME", "");
+ ui::GlobalManager::OpenResZip(L"resources.zip", "");
ui::GlobalManager::Startup(L"resources\\", ui::CreateControlCallback(), false);
#endif
@@ -61,4 +65,4 @@ void MainThread::Cleanup()
ui::GlobalManager::Shutdown();
SetThreadWasQuitProperly(true);
nbase::ThreadManager::UnregisterThread();
-}
+}
\ No newline at end of file
diff --git a/examples/cef/cef.vcxproj b/examples/cef/cef.vcxproj
index 98cd777f..7be0a182 100644
--- a/examples/cef/cef.vcxproj
+++ b/examples/cef/cef.vcxproj
@@ -23,13 +23,13 @@
{B8588C07-9CE2-456C-83B1-86E4B65D4108}
Win32Proj
cef
- 10.0.17763.0
+ 10.0
Application
true
- v120_xp
+ v142
Unicode
diff --git a/examples/controls/controls.vcxproj b/examples/controls/controls.vcxproj
index 456957b6..1d239846 100644
--- a/examples/controls/controls.vcxproj
+++ b/examples/controls/controls.vcxproj
@@ -23,19 +23,19 @@
{8BD95440-9000-4745-8011-27DD553EF06F}
Win32Proj
controls
- 10.0.17763.0
+ 10.0
Application
true
- v120_xp
+ v142
Unicode
Application
false
- v120_xp
+ v142
true
Unicode
@@ -75,7 +75,7 @@
$(ProjectDir)..\..\tmp\$(PlatformName)\$(ProjectName)\$(Configuration)\
$(ProjectName)_d
..\..\bin\
- ..\..\;$(IncludePath)
+ ..\..\;$(ProjectDir)..\..\duilib;$(IncludePath)
$(LibraryPath)
@@ -107,7 +107,7 @@
Level3
Disabled
true
- WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
true
MultiThreadedDebug
diff --git a/examples/controls/controls_form.cpp b/examples/controls/controls_form.cpp
index 7206e669..d5d15c9e 100644
--- a/examples/controls/controls_form.cpp
+++ b/examples/controls/controls_form.cpp
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "controls_form.h"
+#include "Utils\DpiManager.h"
#include
@@ -9,7 +10,6 @@ ControlForm::ControlForm()
{
}
-
ControlForm::~ControlForm()
{
}
@@ -29,6 +29,16 @@ std::wstring ControlForm::GetWindowClassName() const
return kClassName;
}
+bool ComboChange(ui::EventArgs* ev) {
+ if (nullptr != ev) {
+ printf("%d\r\n", ev->Type);
+ auto p = static_cast(ev->pSender);
+ auto text = p->GetText();
+ wprintf(L"%s\r\n", text.c_str());
+ }
+ return true;
+}
+
void ControlForm::InitWindow()
{
/**
@@ -37,7 +47,7 @@ void ControlForm::InitWindow()
* 不要在每次使用的时候都需要 FindControl,否则会影响性能代码不易读
*/
- /* Initialize ListBox data */
+ /* Initialize ListBox data */
ui::ListBox* list = dynamic_cast(FindControl(L"list"));
for (auto i = 0; i < 30; i++)
{
@@ -82,7 +92,7 @@ void ControlForm::InitWindow()
element->SetText(nbase::StringPrintf(L"Combo element %d", i));
combo->Add(element);
}
-
+ combo->AttachAllEvents(ComboChange);
/* Load xml file content in global misc thread, and post update RichEdit task to UI thread */
StdClosure closure = [this]() {
std::streamoff length = 0;
@@ -103,7 +113,9 @@ void ControlForm::InitWindow()
}
// Post task to UI thread
- nbase::ThreadManager::PostTask(kThreadUI, nbase::Bind(&ControlForm::OnLoadedResourceFile, this, xml)); // or Post2UI(nbase::Bind(&ControlForm::OnLoadedResourceFile, this, xml));
+ nbase::ThreadManager::PostTask(kThreadUI,
+ nbase::Bind(&ControlForm::OnLoadedResourceFile, this, xml));
+ // or Post2UI(nbase::Bind(&ControlForm::OnLoadedResourceFile, this, xml));
};
// Using ToWeakCallback to protect closure when if [ControlForm] was destoryed
nbase::ThreadManager::PostTask(kThreadGlobalMisc, ToWeakCallback(closure)); // or Post2GlobalMisc(ToWeakCallback(closure));
@@ -111,9 +123,11 @@ void ControlForm::InitWindow()
/* Post repeat task to update progress value 200 milliseconds once */
StdClosure repeat_task = [this]() {
nbase::TimeDelta time_delta = nbase::TimeDelta::FromMicroseconds(nbase::Time::Now().ToInternalValue());
- nbase::ThreadManager::PostTask(kThreadUI, nbase::Bind(&ControlForm::OnProgressValueChagned, this, time_delta.ToMilliseconds() % 100));
+ nbase::ThreadManager::PostTask(kThreadUI,
+ nbase::Bind(&ControlForm::OnProgressValueChagned, this, time_delta.ToMilliseconds() % 100));
};
- nbase::ThreadManager::PostRepeatedTask(kThreadGlobalMisc, ToWeakCallback(repeat_task), nbase::TimeDelta::FromMilliseconds(200));
+ nbase::ThreadManager::PostRepeatedTask(kThreadGlobalMisc,
+ ToWeakCallback(repeat_task), nbase::TimeDelta::FromMilliseconds(200));
/* Show settings menu */
ui::Button* settings = dynamic_cast(FindControl(L"settings"));
@@ -128,7 +142,7 @@ void ControlForm::InitWindow()
ui::STRINGorID xml(L"settings_menu.xml");
pMenu->Init(xml, _T("xml"), point);
return true;
- });
+ });
}
LRESULT ControlForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
@@ -154,7 +168,7 @@ void ControlForm::OnProgressValueChagned(float value)
progress->SetValue(value);
auto circleprogress = dynamic_cast(FindControl(L"circleprogress"));
circleprogress->SetValue(value);
- TCHAR szBuffer[32] = {0};
+ TCHAR szBuffer[32] = { 0 };
swprintf_s(szBuffer, _T("%.0f%%"), value);
circleprogress->SetText(szBuffer);
-}
+}
\ No newline at end of file
diff --git a/examples/controls/main.cpp b/examples/controls/main.cpp
index 91a358fb..b3d283c8 100644
--- a/examples/controls/main.cpp
+++ b/examples/controls/main.cpp
@@ -4,12 +4,21 @@
#include "stdafx.h"
#include "main.h"
#include "controls_form.h"
+#include "Utils\DpiManager.h"
+
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
+ AllocConsole();
+ freopen("CONOUT$", "w", stdout);
+
+ auto dpiManager = ui::DpiManager::GetInstance();
+ dpiManager->SetAdaptDPI(); // 璁剧疆閫傞厤鑷姩dpi
+ printf("dpi is %d\r\n",dpiManager->GetDPIFromRegistry());
+
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
diff --git a/examples/controls/main.h b/examples/controls/main.h
index 451ed300..ee2701e7 100644
--- a/examples/controls/main.h
+++ b/examples/controls/main.h
@@ -10,7 +10,7 @@
class MiscThread : public nbase::FrameworkThread
{
public:
- MiscThread(enum ThreadId thread_id, const char *name)
+ MiscThread(enum ThreadId thread_id, const char* name)
: FrameworkThread(name)
, thread_id_(thread_id) {}
diff --git a/examples/examples.sln b/examples/examples.sln
index 639e2c63..c78aa6fb 100644
--- a/examples/examples.sln
+++ b/examples/examples.sln
@@ -1,7 +1,7 @@
锘
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.40629.0
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31229.75
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B2087994-3DF6-4A57-B8C6-6F744520D7FA}"
EndProject
@@ -29,6 +29,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "duilib", "..\duilib\duilib.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ui_components", "..\ui_components\ui_components.vcxproj", "{0149BA6E-3C0A-426D-AA0A-0B9EC7742F19}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "proto_debuger", "proto_debuger\proto_debuger.vcxproj", "{6D78D8B7-1617-4ED4-B155-94369FC3E73C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "catch_test", "catch_test\catch_test.vcxproj", "{91850193-0E5E-4983-9D11-F9875805D91E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -123,6 +127,22 @@ Global
{0149BA6E-3C0A-426D-AA0A-0B9EC7742F19}.Release|Win32.Build.0 = Release|Win32
{0149BA6E-3C0A-426D-AA0A-0B9EC7742F19}.Release|x64.ActiveCfg = Release|x64
{0149BA6E-3C0A-426D-AA0A-0B9EC7742F19}.Release|x64.Build.0 = Release|x64
+ {6D78D8B7-1617-4ED4-B155-94369FC3E73C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6D78D8B7-1617-4ED4-B155-94369FC3E73C}.Debug|Win32.Build.0 = Debug|Win32
+ {6D78D8B7-1617-4ED4-B155-94369FC3E73C}.Debug|x64.ActiveCfg = Debug|x64
+ {6D78D8B7-1617-4ED4-B155-94369FC3E73C}.Debug|x64.Build.0 = Debug|x64
+ {6D78D8B7-1617-4ED4-B155-94369FC3E73C}.Release|Win32.ActiveCfg = Release|Win32
+ {6D78D8B7-1617-4ED4-B155-94369FC3E73C}.Release|Win32.Build.0 = Release|Win32
+ {6D78D8B7-1617-4ED4-B155-94369FC3E73C}.Release|x64.ActiveCfg = Release|x64
+ {6D78D8B7-1617-4ED4-B155-94369FC3E73C}.Release|x64.Build.0 = Release|x64
+ {91850193-0E5E-4983-9D11-F9875805D91E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {91850193-0E5E-4983-9D11-F9875805D91E}.Debug|Win32.Build.0 = Debug|Win32
+ {91850193-0E5E-4983-9D11-F9875805D91E}.Debug|x64.ActiveCfg = Debug|x64
+ {91850193-0E5E-4983-9D11-F9875805D91E}.Debug|x64.Build.0 = Debug|x64
+ {91850193-0E5E-4983-9D11-F9875805D91E}.Release|Win32.ActiveCfg = Release|Win32
+ {91850193-0E5E-4983-9D11-F9875805D91E}.Release|Win32.Build.0 = Release|Win32
+ {91850193-0E5E-4983-9D11-F9875805D91E}.Release|x64.ActiveCfg = Release|x64
+ {91850193-0E5E-4983-9D11-F9875805D91E}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -136,6 +156,7 @@ Global
{A9D6DC71-C0DC-4549-AEA0-3B15B44E86A9} = {1DA0A8E2-5832-42FC-83F7-2CDCAD379C90}
{8BD95440-9000-4745-8011-27DD553EF06F} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
{E35589C6-9509-4116-996F-1D045C2DACAE} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
+ {91850193-0E5E-4983-9D11-F9875805D91E} = {B2087994-3DF6-4A57-B8C6-6F744520D7FA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {68CA0970-4242-4E4F-94D2-C19760FCA05D}
diff --git a/examples/layouts/layouts.vcxproj b/examples/layouts/layouts.vcxproj
index 09e6bd26..a2c201f1 100644
--- a/examples/layouts/layouts.vcxproj
+++ b/examples/layouts/layouts.vcxproj
@@ -23,13 +23,13 @@
{2BFFA1EE-039D-479E-9BCC-2D12F8AEDD16}
Win32Proj
layouts
- 10.0.17763.0
+ 10.0
Application
true
- v120_xp
+ v142
Unicode
diff --git a/examples/multi_browser/multi_browser.vcxproj b/examples/multi_browser/multi_browser.vcxproj
index 71731080..fccfc6b2 100644
--- a/examples/multi_browser/multi_browser.vcxproj
+++ b/examples/multi_browser/multi_browser.vcxproj
@@ -22,12 +22,13 @@
{FDB5539F-1060-4975-B603-B66454C8C897}
Win32Proj
multi_browser
+ 10.0
Application
true
- v120_xp
+ v142
Unicode
diff --git a/examples/proto_debuger/base_form.cpp b/examples/proto_debuger/base_form.cpp
new file mode 100644
index 00000000..a1188da9
--- /dev/null
+++ b/examples/proto_debuger/base_form.cpp
@@ -0,0 +1,86 @@
+#include "base_form.h"
+#include "new_monitor_form.h"
+
+const std::wstring BasicForm::kClassName = L"Basic";
+#define WM_USER_POS_CHANGED (WM_USER + 2)
+
+BasicForm::BasicForm()
+{
+}
+
+BasicForm::~BasicForm()
+{
+}
+
+std::wstring BasicForm::GetSkinFolder()
+{
+ return L"basic";
+}
+
+std::wstring BasicForm::GetSkinFile()
+{
+ return L"basic.xml";
+}
+
+std::wstring BasicForm::GetWindowClassName() const
+{
+ return kClassName;
+}
+
+
+LRESULT BasicForm::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_USER_POS_CHANGED) {
+ NewMonitorForm* window = new NewMonitorForm();
+ window->Create(NULL, NewMonitorForm::kClassName.c_str(), WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & WS_SIZEBOX, 0);
+ window->CenterWindow();
+ window->ShowModalFake(this->m_hWnd);
+ nim_comp::Toast::ShowToast(L"自定义消息被调用", 1000, this->GetHWND());
+ }
+ return WindowImplBase::HandleMessage(uMsg, wParam, lParam);
+}
+
+void BasicForm::InitWindow()
+{
+ /* Show settings menu */
+ ui::Button* settings = dynamic_cast(FindControl(L"test_customize"));
+ if (nullptr != settings) {
+ settings->AttachClick([this](ui::EventArgs* args) {
+ printf("%d\r\n", ::PostMessage(this->GetHWND(), WM_USER_POS_CHANGED, 0, 0));
+ return true;
+ });
+ }
+ ui::TreeView* tree = dynamic_cast(FindControl(L"tree"));
+ if (nullptr != tree) {
+ ui::TreeNode* parent_node = nullptr;
+ for (auto j = 0; j < 8; j++)
+ {
+ ui::TreeNode* node = new ui::TreeNode;
+ node->SetClass(L"listitem");
+ node->SetFixedHeight(20);
+ if (parent_node)
+ {
+ node->SetText(nbase::StringPrintf(L"Child node %d", j));
+ node->SetMargin({ 10, 0, 0, 0 });
+ parent_node->AddChildNode(node);
+ }
+ else
+ {
+ node->SetText(nbase::StringPrintf(L"Parent node", j));
+ tree->GetRootNode()->AddChildNode(node);
+ parent_node = node;
+ parent_node->AttachClick([this](ui::EventArgs* args) {
+ printf("%d\r\n", ::PostMessage(this->GetHWND(), WM_USER_POS_CHANGED, 0, 0));
+ return true;
+ });
+ }
+ }
+ }
+
+}
+
+LRESULT BasicForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ PostQuitMessage(0L);
+ return __super::OnClose(uMsg, wParam, lParam, bHandled);
+}
\ No newline at end of file
diff --git a/examples/proto_debuger/base_form.h b/examples/proto_debuger/base_form.h
new file mode 100644
index 00000000..795724ab
--- /dev/null
+++ b/examples/proto_debuger/base_form.h
@@ -0,0 +1,46 @@
+#pragma once
+
+// C runtime header
+#ifdef __cplusplus
+#include
+#include
+#include
+#include
+#endif
+
+// base header
+#include "base/base.h"
+
+// duilib
+#include "duilib/UIlib.h"
+#include "ui_components/ui_components.h"
+
+
+class BasicForm : public ui::WindowImplBase
+{
+public:
+ BasicForm();
+ ~BasicForm();
+
+ /**
+ * 一下三个接口是必须要覆写的接口,父类会调用这三个接口来构建窗口
+ * GetSkinFolder 接口设置你要绘制的窗口皮肤资源路径
+ * GetSkinFile 接口设置你要绘制的窗口的 xml 描述文件
+ * GetWindowClassName 接口设置窗口唯一的类名称
+ */
+ virtual std::wstring GetSkinFolder() override;
+ virtual std::wstring GetSkinFile() override;
+ virtual std::wstring GetWindowClassName() const override;
+ virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
+ /**
+ * 收到 WM_CREATE 消息时该函数会被调用,通常做一些控件初始化的操作
+ */
+ void InitWindow() override;
+
+ /**
+ * 收到 WM_CLOSE 消息时该函数会被调用
+ */
+ virtual LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+ static const std::wstring kClassName;
+};
diff --git a/examples/proto_debuger/main.cpp b/examples/proto_debuger/main.cpp
new file mode 100644
index 00000000..f2be0184
--- /dev/null
+++ b/examples/proto_debuger/main.cpp
@@ -0,0 +1,67 @@
+// basic.cpp : 定义应用程序的入口点。
+//
+
+#include "main.h"
+#include "base_form.h"
+#include"resource1.h"
+#include
+
+enum ThreadId
+{
+ kThreadUI
+};
+
+int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
+ _In_opt_ HINSTANCE hPrevInstance,
+ _In_ LPWSTR lpCmdLine,
+ _In_ int nCmdShow)
+{
+ AllocConsole();
+ freopen("CONOUT$", "w", stdout);
+
+ UNREFERENCED_PARAMETER(hPrevInstance);
+ UNREFERENCED_PARAMETER(lpCmdLine);
+
+ // 创建主线程
+ MainThread thread;
+ // 执行主线程循环
+ thread.RunOnCurrentThreadWithLoop(nbase::MessageLoop::kUIMessageLoop);
+ return 0;
+}
+
+void MainThread::Init()
+{
+ nbase::ThreadManager::RegisterThread(kThreadUI);
+
+ // 获取资源路径,初始化全局参数
+ std::wstring theme_dir = nbase::win32::GetCurrentModuleDirectory();
+ wprintf(L"%s\r\n", theme_dir);
+#if 1
+ // Debug 模式下使用本地文件夹作为资源
+ // 默认皮肤使用 resources\\themes\\default
+ // 默认语言使用 resources\\lang\\zh_CN
+ // 如需修改请指定 Startup 最后两个参数
+ ui::GlobalManager::Startup(theme_dir + L"resources\\", ui::CreateControlCallback(), false);
+#else
+ // Release 模式下使用资源中的压缩包作为资源
+ // 资源被导入到资源列表分类为 THEME,资源名称为 IDR_THEME
+ // 如果资源使用的是本地的 zip 文件而非资源中的 zip 压缩包
+ // 可以使用 OpenResZip 另一个重载函数打开本地的资源压缩包
+ ui::GlobalManager::OpenResZip(MAKEINTRESOURCE(IDR_THEME2), L"THEME", "");
+ //ui::GlobalManager::OpenResZip(L"resources.zip", "");
+ ui::GlobalManager::Startup(L"resources\\", ui::CreateControlCallback(), false);
+#endif
+
+ // 创建一个默认带有阴影的居中窗口
+ BasicForm* window = new BasicForm();
+ window->Create(NULL, BasicForm::kClassName.c_str(), WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & WS_SIZEBOX, 0);
+ window->CenterWindow();
+ window->ShowWindow();
+}
+
+void MainThread::Cleanup()
+{
+ ui::GlobalManager::Shutdown();
+ SetThreadWasQuitProperly(true);
+ nbase::ThreadManager::UnregisterThread();
+}
\ No newline at end of file
diff --git a/examples/proto_debuger/main.h b/examples/proto_debuger/main.h
new file mode 100644
index 00000000..38c9270e
--- /dev/null
+++ b/examples/proto_debuger/main.h
@@ -0,0 +1,40 @@
+#pragma once
+
+
+// C runtime header
+#include
+#include
+#include
+#include
+
+// base header
+#include "base/base.h"
+
+// duilib
+#include "duilib/UIlib.h"
+
+/** @class MainThread
+* @brief 主线程(UI线程)类,继承 nbase::FrameworkThread
+* @copyright (c) 2015, NetEase Inc. All rights reserved
+* @author towik
+* @date 2015/1/1
+*/
+class MainThread : public nbase::FrameworkThread
+{
+public:
+ MainThread() : nbase::FrameworkThread("MainThread") {}
+ virtual ~MainThread() {}
+
+private:
+ /**
+ * 虚函数,初始化主线程
+ * @return void 无返回值
+ */
+ virtual void Init() override;
+
+ /**
+ * 虚函数,主线程退出时,做一些清理工作
+ * @return void 无返回值
+ */
+ virtual void Cleanup() override;
+};
diff --git a/examples/proto_debuger/new_monitor_form.cpp b/examples/proto_debuger/new_monitor_form.cpp
new file mode 100644
index 00000000..2a76d49b
--- /dev/null
+++ b/examples/proto_debuger/new_monitor_form.cpp
@@ -0,0 +1,41 @@
+#include "new_monitor_form.h"
+const std::wstring NewMonitorForm::kClassName = L"Basic";
+
+NewMonitorForm::NewMonitorForm()
+{
+
+}
+
+NewMonitorForm::~NewMonitorForm()
+{
+}
+
+std::wstring NewMonitorForm::GetSkinFolder()
+{
+ return L"basic";
+}
+
+std::wstring NewMonitorForm::GetSkinFile()
+{
+ return L"newmonitor.xml";
+}
+
+std::wstring NewMonitorForm::GetWindowClassName() const
+{
+ return kClassName;
+}
+
+LRESULT NewMonitorForm::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ return WindowImplBase::HandleMessage(uMsg, wParam, lParam);
+}
+
+void NewMonitorForm::InitWindow()
+{
+}
+
+LRESULT NewMonitorForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ PostQuitMessage(0L);
+ return __super::OnClose(uMsg, wParam, lParam, bHandled);
+}
diff --git a/examples/proto_debuger/new_monitor_form.h b/examples/proto_debuger/new_monitor_form.h
new file mode 100644
index 00000000..1a1ee269
--- /dev/null
+++ b/examples/proto_debuger/new_monitor_form.h
@@ -0,0 +1,46 @@
+#pragma once
+// C runtime header
+#ifdef __cplusplus
+#include
+#include
+#include
+#include
+#endif
+
+// base header
+#include "base/base.h"
+
+// duilib
+#include "duilib/UIlib.h"
+#include "ui_components/ui_components.h"
+
+
+class NewMonitorForm : public ui::WindowImplBase
+{
+public:
+ NewMonitorForm();
+ ~NewMonitorForm();
+
+ /**
+ * 一下三个接口是必须要覆写的接口,父类会调用这三个接口来构建窗口
+ * GetSkinFolder 接口设置你要绘制的窗口皮肤资源路径
+ * GetSkinFile 接口设置你要绘制的窗口的 xml 描述文件
+ * GetWindowClassName 接口设置窗口唯一的类名称
+ */
+ virtual std::wstring GetSkinFolder() override;
+ virtual std::wstring GetSkinFile() override;
+ virtual std::wstring GetWindowClassName() const override;
+ virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
+ /**
+ * 收到 WM_CREATE 消息时该函数会被调用,通常做一些控件初始化的操作
+ */
+ void InitWindow() override;
+
+ /**
+ * 收到 WM_CLOSE 消息时该函数会被调用
+ */
+ virtual LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+ static const std::wstring kClassName;
+};
+
diff --git a/examples/proto_debuger/proto_debuger.rc b/examples/proto_debuger/proto_debuger.rc
new file mode 100644
index 00000000..9339e3e0
--- /dev/null
+++ b/examples/proto_debuger/proto_debuger.rc
@@ -0,0 +1,76 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource1.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// 中文(简体,中国) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+#pragma code_page(936)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource1.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// THEME
+//
+
+IDR_THEME2 THEME "E:\\NIM_Duilib_Framework\\examples\\proto_debuger\\Release\\resources.zip"
+
+#endif // 中文(简体,中国) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/examples/proto_debuger/proto_debuger.vcxproj b/examples/proto_debuger/proto_debuger.vcxproj
new file mode 100644
index 00000000..01103b6e
--- /dev/null
+++ b/examples/proto_debuger/proto_debuger.vcxproj
@@ -0,0 +1,181 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {6d78d8b7-1617-4ed4-b155-94369fc3e73c}
+ protodebuger
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(VC_ReferencesPath_x86);
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\;$(IncludePath)
+
+
+ false
+ ../../;$(VC_IncludePath);$(WindowsSDK_IncludePath);
+
+
+ true
+
+
+ false
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ Windows
+ true
+ LinkVerbose
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ {8d9a6595-717a-41c8-b468-0011a72be3d1}
+
+
+ {e106acd7-4e53-4aee-942b-d0dd426db34e}
+
+
+ {0149ba6e-3c0a-426d-aa0a-0b9ec7742f19}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/proto_debuger/proto_debuger.vcxproj.filters b/examples/proto_debuger/proto_debuger.vcxproj.filters
new file mode 100644
index 00000000..40840db6
--- /dev/null
+++ b/examples/proto_debuger/proto_debuger.vcxproj.filters
@@ -0,0 +1,55 @@
+锘
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+
+
+ 璧勬簮鏂囦欢
+
+
+
+
+ 璧勬簮鏂囦欢
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/proto_debuger/resource1.h b/examples/proto_debuger/resource1.h
new file mode 100644
index 00000000..46f610bd
--- /dev/null
+++ b/examples/proto_debuger/resource1.h
@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ 生成的包含文件。
+// 供 proto_debuger.rc 使用
+//
+#define IDR_ACCELERATOR1 101
+#define IDR_THEME2 103
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40002
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/examples/richlist/richlist.vcxproj b/examples/richlist/richlist.vcxproj
index 176fa5f7..74e4d66b 100644
--- a/examples/richlist/richlist.vcxproj
+++ b/examples/richlist/richlist.vcxproj
@@ -23,13 +23,13 @@
{878F5BF0-652A-4FDB-992B-BB7F26D62F0D}
Win32Proj
richlist
- 10.0.17763.0
+ 10.0
Application
true
- v120_xp
+ v142
Unicode
diff --git a/examples/virtualbox/main.cpp b/examples/virtualbox/main.cpp
index 62c0d1fb..cd02ea8e 100644
--- a/examples/virtualbox/main.cpp
+++ b/examples/virtualbox/main.cpp
@@ -43,7 +43,7 @@ void MainThread::Init()
// 获取资源路径,初始化全局参数
std::wstring theme_dir = nbase::win32::GetCurrentModuleDirectory();
- ui::GlobalManager::Startup(theme_dir + L"resources\\", MyCreateControlCallback, false);
+ ui::GlobalManager::Startup(theme_dir + L"resources\\", MyCreateControlCallback, true);
// 创建一个默认带有阴影的居中窗口
MainForm* window = new MainForm();
diff --git a/examples/virtualbox/main_form.cpp b/examples/virtualbox/main_form.cpp
index ded6a87f..cd824201 100644
--- a/examples/virtualbox/main_form.cpp
+++ b/examples/virtualbox/main_form.cpp
@@ -46,8 +46,6 @@ void MainForm::InitWindow()
m_DataProvider = new Provider;
m_pTileList->SetDataProvider(m_DataProvider);
-
-
}
LRESULT MainForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
@@ -72,7 +70,7 @@ bool MainForm::OnClicked(ui::EventArgs* args)
if (m_CheckBoxItemCenter->IsSelected())
{
m_pTileList->SetAttribute(L"width", L"auto");
- m_pTileList->SetAttribute(L"halign", L"center");
+ m_pTileList->SetAttribute(L"halign", L"left");
}
else {
m_pTileList->SetAttribute(L"width", L"stretch");
@@ -93,7 +91,7 @@ bool MainForm::OnClicked(ui::EventArgs* args)
}
else if (sName == L"btn_update")
{
- m_DataProvider->ChangeTaskName(_ttoi(m_EditUpdate->GetText().c_str())-1,
+ m_DataProvider->ChangeTaskName(_ttoi(m_EditUpdate->GetText().c_str()) - 1,
m_EditTaskName->GetText());
}
else if (sName == L"btn_delete")
diff --git a/examples/virtualbox/virtualbox.vcxproj b/examples/virtualbox/virtualbox.vcxproj
index 0fbb98c1..99288590 100644
--- a/examples/virtualbox/virtualbox.vcxproj
+++ b/examples/virtualbox/virtualbox.vcxproj
@@ -15,12 +15,13 @@
Win32Proj
VirtualBox
virtualbox
+ 10.0
Application
true
- v120_xp
+ v142
Unicode
diff --git a/third_party/cef_wrapper/libcef_dll_wrapper.vcxproj b/third_party/cef_wrapper/libcef_dll_wrapper.vcxproj
index 0ab73629..24f9ab63 100644
--- a/third_party/cef_wrapper/libcef_dll_wrapper.vcxproj
+++ b/third_party/cef_wrapper/libcef_dll_wrapper.vcxproj
@@ -23,13 +23,14 @@
Win32Proj
Win32
libcef_dll_wrapper
+ 10.0
StaticLibrary
false
Unicode
- v120_xp
+ v142
StaticLibrary
@@ -41,7 +42,7 @@
StaticLibrary
false
Unicode
- v120_xp
+ v142
StaticLibrary
diff --git a/ui_components/modal_wnd/async_modal_runner.h b/ui_components/modal_wnd/async_modal_runner.h
index 10706ccb..1a609dd7 100644
--- a/ui_components/modal_wnd/async_modal_runner.h
+++ b/ui_components/modal_wnd/async_modal_runner.h
@@ -35,10 +35,12 @@ public:
// the ownership of the dialog
bool DoModal(ModalWndBase *dlg);
void CancelModalThenExit();
+ template
+ friend class Ref_count_obj;
private:
- template
- friend class std::_Ref_count_obj;
+
+
friend class AsyncModalRunnerManager;
friend class std::shared_ptr;
diff --git a/ui_components/ui_components.vcxproj b/ui_components/ui_components.vcxproj
index 79d1bd28..7c7902da 100644
--- a/ui_components/ui_components.vcxproj
+++ b/ui_components/ui_components.vcxproj
@@ -23,19 +23,19 @@
{0149BA6E-3C0A-426D-AA0A-0B9EC7742F19}
Win32Proj
uicomponents
- 10.0.17763.0
+ 10.0
StaticLibrary
true
- v120_xp
+ v142
Unicode
StaticLibrary
false
- v120_xp
+ v142
true
Unicode
@@ -100,6 +100,7 @@
true
.\;..\;..\third_party\cef_wrapper\;%(AdditionalIncludeDirectories)
MultiThreadedDebug
+ stdcpp17
Windows
@@ -200,7 +201,6 @@
-
@@ -228,7 +228,6 @@
-
diff --git a/ui_components/ui_components.vcxproj.filters b/ui_components/ui_components.vcxproj.filters
index d0ef58d5..13ed0247 100644
--- a/ui_components/ui_components.vcxproj.filters
+++ b/ui_components/ui_components.vcxproj.filters
@@ -66,9 +66,6 @@
modal_wnd
-
- modal_wnd
-
modal_wnd
@@ -149,9 +146,6 @@
modal_wnd
-
- modal_wnd
-
modal_wnd
diff --git a/ui_components/windows_manager/window_ex.h b/ui_components/windows_manager/window_ex.h
index 6c858b0b..098c1060 100644
--- a/ui_components/windows_manager/window_ex.h
+++ b/ui_components/windows_manager/window_ex.h
@@ -3,86 +3,86 @@
namespace nim_comp
{
-/** @class WindowEx
- * @brief 所有窗体的基类
- * @copyright (c) 2015, NetEase Inc. All rights reserved
- * @date 2015/9/16
- */
-class WindowEx : public ui::WindowImplBase
-{
-public:
- WindowEx();
- virtual ~WindowEx();
+ /** @class WindowEx
+ * @brief 所有窗体的基类
+ * @copyright (c) 2015, NetEase Inc. All rights reserved
+ * @date 2015/9/16
+ */
+ class WindowEx : public ui::WindowImplBase
+ {
+ public:
+ WindowEx();
+ virtual ~WindowEx();
+
+ /**
+ * 创建窗口
+ * @param[in] hwndParent 父窗口句柄
+ * @param[in] pstrName 窗口名称
+ * @param[in] dwStyle 窗口样式
+ * @param[in] dwExStyle 窗口扩展样式
+ * @param[in] isLayeredWindow 是否创建分层窗口
+ * @param[in] rc 窗口位置
+ * @return HWND 窗口句柄
+ */
+ virtual HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle,
+ bool isLayeredWindow = true, const ui::UiRect& rc = ui::UiRect(0, 0, 0, 0)) override;
+
+ /**
+ * 处理窗口被销毁的消息
+ * @param[in] uMsg 消息
+ * @param[in] wParam 参数
+ * @param[in] lParam 参数
+ * @param[out] b
+ d 消息是否被处理
+ * @return LRESULT 处理结果
+ */
+ virtual LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+ /**
+ * 处理ESC键单击的消息
+ * @param[out] bHandled 消息是否被处理
+ * @return void 无返回值
+ */
+ virtual void OnEsc(BOOL& bHandled);
+
+ /**
+ * 获取窗口类名的接口
+ * @return wstring 窗口类名
+ */
+ virtual std::wstring GetWindowClassName(void) const = 0;
+
+ /**
+ * 获取窗口id的接口
+ * @return wstring 窗口id
+ */
+ virtual std::wstring GetWindowId(void) const = 0;
+
+ /**
+ * 处理窗口消息
+ * @param[in] uMsg 消息
+ * @param[in] wParam 参数
+ * @param[in] lParam 参数
+ * @return LRESULT 处理结果
+ */
+ virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ /**
+ * 从WindowManager中注册自己
+ * @return bool true 注册成功,false 注册失败
+ */
+ bool RegisterWnd();
+
+ /**
+ * 从WindowManager中反注册自己
+ * @return void 无返回值
+ */
+ void UnRegisterWnd();
+ };
/**
- * 创建窗口
- * @param[in] hwndParent 父窗口句柄
- * @param[in] pstrName 窗口名称
- * @param[in] dwStyle 窗口样式
- * @param[in] dwExStyle 窗口扩展样式
- * @param[in] isLayeredWindow 是否创建分层窗口
- * @param[in] rc 窗口位置
- * @return HWND 窗口句柄
- */
- virtual HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle,
- bool isLayeredWindow = true, const ui::UiRect& rc = ui::UiRect(0, 0, 0, 0)) override;
-
- /**
- * 处理窗口被销毁的消息
- * @param[in] uMsg 消息
- * @param[in] wParam 参数
- * @param[in] lParam 参数
- * @param[out] bHandled 消息是否被处理
- * @return LRESULT 处理结果
- */
- virtual LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
- /**
- * 处理ESC键单击的消息
- * @param[out] bHandled 消息是否被处理
- * @return void 无返回值
- */
- virtual void OnEsc(BOOL &bHandled);
-
- /**
- * 获取窗口类名的接口
- * @return wstring 窗口类名
- */
- virtual std::wstring GetWindowClassName(void) const = 0;
-
- /**
- * 获取窗口id的接口
- * @return wstring 窗口id
- */
- virtual std::wstring GetWindowId(void) const = 0;
-
- /**
- * 处理窗口消息
- * @param[in] uMsg 消息
- * @param[in] wParam 参数
- * @param[in] lParam 参数
- * @return LRESULT 处理结果
- */
- virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
-
-private:
- /**
- * 从WindowManager中注册自己
- * @return bool true 注册成功,false 注册失败
- */
- bool RegisterWnd();
-
- /**
- * 从WindowManager中反注册自己
- * @return void 无返回值
- */
- void UnRegisterWnd();
-};
-
-/**
-* 获取弹出窗口可以显示在右下角位置的坐标
-* @return POINT 窗口坐标
-*/
-POINT GetPopupWindowPos(WindowEx* window);
-
+ * 获取弹出窗口可以显示在右下角位置的坐标
+ * @return POINT 窗口坐标
+ */
+ POINT GetPopupWindowPos(WindowEx* window);
}
\ No newline at end of file