diff --git a/Tools/GeneratePortalBrowserXMLdoc.bat b/Tools/GeneratePortalBrowserXMLdoc.bat deleted file mode 100644 index a12706625..000000000 --- a/Tools/GeneratePortalBrowserXMLdoc.bat +++ /dev/null @@ -1,7 +0,0 @@ -rem SETLOCAL ENABLEDELAYEDEXPANSION -rem set START_DIR=%~d0%~p0%~nx0 -rem set START_DIR=!START_DIR:%~0=! -rem echo %START_DIR% -rem cd "%~d0%~p0" -rem msxsl ..\compiled\PortalBrowser\PortalBrowser.xsd XMLdocTemplate.xsl -t -o ..\compiled\PortalBrowser\XMLformatDoc.htm -rem cd %START_DIR% \ No newline at end of file diff --git a/Tools/UpdateGitRevision.bat b/Tools/UpdateGitRevision.bat index b9aae3975..a641f9e16 100644 --- a/Tools/UpdateGitRevision.bat +++ b/Tools/UpdateGitRevision.bat @@ -1,4 +1,3 @@ -@echo off set NOCOMMIT= set VERSION_NUM=503 diff --git a/Tools/generate-version.bat b/Tools/generate-version.bat index ce269c81e..50e76fae0 100644 --- a/Tools/generate-version.bat +++ b/Tools/generate-version.bat @@ -1,4 +1,3 @@ -@echo off set file=%1ver.inc set tmpfile=%1ver.inc.tmp diff --git a/client/CryptoManager.cpp b/client/CryptoManager.cpp index dd9c7624d..79e431cbe 100644 --- a/client/CryptoManager.cpp +++ b/client/CryptoManager.cpp @@ -361,10 +361,10 @@ int CryptoManager::getKeyLength(TLSTmpKeys key) DH* CryptoManager::getTmpDH(int keyLen) { if (keyLen < 2048) - return NULL; + return nullptr; DH* tmpDH = DH_new(); - if (!tmpDH) return NULL; + if (!tmpDH) return nullptr; // From RFC 3526; checked via http://wiki.openssl.org/index.php/Diffie-Hellman_parameters#Validating_Parameters switch (keyLen) @@ -396,7 +396,7 @@ DH* CryptoManager::getTmpDH(int keyLen) 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; - tmpDH->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), 0); + tmpDH->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), nullptr); break; } @@ -448,7 +448,7 @@ DH* CryptoManager::getTmpDH(int keyLen) 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; - tmpDH->p = BN_bin2bn(dh4096_p, sizeof(dh4096_p), 0); + tmpDH->p = BN_bin2bn(dh4096_p, sizeof(dh4096_p), nullptr); break; } } @@ -458,29 +458,32 @@ DH* CryptoManager::getTmpDH(int keyLen) 0x02, }; - tmpDH->g = BN_bin2bn(dh_g, sizeof(dh_g), 0); + tmpDH->g = BN_bin2bn(dh_g, sizeof(dh_g), nullptr); if (!tmpDH->p || !tmpDH->g) { DH_free(tmpDH); - return NULL; + return nullptr; + } + else + { + return tmpDH; } - else return tmpDH; } RSA* CryptoManager::getTmpRSA(int keyLen) { if (keyLen < 2048) - return NULL; + return nullptr; RSA* tmpRSA = RSA_new(); BIGNUM* bn = BN_new(); - if (!bn || !BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(tmpRSA, keyLen, bn, NULL)) + if (!bn || !BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(tmpRSA, keyLen, bn, nullptr)) { if (bn) BN_free(bn); RSA_free(tmpRSA); - return NULL; + return nullptr; } BN_free(bn); diff --git a/client/SearchResult.h b/client/SearchResult.h index 49a704c00..97533becf 100644 --- a/client/SearchResult.h +++ b/client/SearchResult.h @@ -228,12 +228,12 @@ class SearchResult : public SearchResultCore string m_hubName; string m_hubURL; - boost::asio::ip::address_v4 m_search_ip4; string m_p2p_guard_text; - bool m_is_p2p_guard_calc; + boost::asio::ip::address_v4 m_search_ip4; uint32_t m_token; UserPtr m_user; bool m_is_tth_check; + bool m_is_p2p_guard_calc; }; #endif diff --git a/compiled/readme_changelog_lite.rtf b/compiled/readme_changelog_lite.rtf index a6a93057d..f5232cdf2 100644 --- a/compiled/readme_changelog_lite.rtf +++ b/compiled/readme_changelog_lite.rtf @@ -7,7 +7,14 @@ \'d2\'e0\'ea\'e6\'e5 \'e0\'ed\'ee\'ed\'e8\'ec\'ed\'ee \'ec\'ee\'e6\'ed\'ee \'e2\'fb\'f1\'ea\'e0\'e7\'fb\'e2\'e0\'f2\'fc \'e7\'e0\'ec\'e5\'f7\'e0\'ed\'e8\'ff \'ee \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'e5 \'ed\'e0 \'f5\'e0\'e1\'e5 \'ef\'ee\'e4\'e4\'e5\'e6\'ea\'e8\par dchub://dc.fly-server.ru\par \par -\lang1033\b\f1\fs20 ===\lang1049\f0 \lang1033\f1 r50\lang1049\f0 4 \lang1033\f1 build 21332 ===\par +\lang1033\b\f1\fs20 ===\lang1049\f0 \lang1033\f1 r50\lang1049\f0 4 \lang1033\f1 build 21352 ===\par +\pard\nowidctlpar\lang1049\b0\f0\fs16 * \'c8\'f1\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'ee \'ef\'e0\'e4\'e5\'ed\'e8\'e5 {\field{\*\fldinst{HYPERLINK "https://github.com/MediaArea/MediaInfoLib/issues/783"}}{\fldrslt{\ul\cf4 https://github.com/MediaArea/MediaInfoLib/issues/783}}}\f0\fs16\par +\pard\lang1033\b\f1\fs20 ===\lang1049\f0 \lang1033\f1 r50\lang1049\f0 4 \lang1033\f1 build 213\lang1049\f0 4\lang1033\f1 6 ===\par +\pard\nowidctlpar\lang1049\b0\f0\fs16 * jsoncpp \par +* libtorrent\par +\pard\lang1033\b\f1\fs20 ===\lang1049\f0 \lang1033\f1 r50\lang1049\f0 4 \lang1033\f1 build 213\lang1049\f0 41\lang1033\f1 ===\par +\pard\nowidctlpar\lang1049\b0\f0\fs16 * \'c8\'f1\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'ee \'ef\'e0\'e4\'e5\'ed\'e8\'e5 {\field{\*\fldinst{HYPERLINK "https://drdump.com/Problem.aspx?ProblemID=364805"}}{\fldrslt{\ul\cf4 https://drdump.com/Problem.aspx?ProblemID=364805}}}\f0\fs16 \par +\pard\lang1033\b\f1\fs20 ===\lang1049\f0 \lang1033\f1 r50\lang1049\f0 4 \lang1033\f1 build 21332 ===\par \pard\nowidctlpar\lang1049\b0\f0\fs16 * \'c8\'f1\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'ee \'ef\'ee\'e4\'ec\'e5\'f0\'e7\'e0\'ed\'e8\'e5 \'ee\'ea\'ee\'ed \'ef\'ee\'e8\'f1\'ea\'e0 \'ef\'f0\'e8 \'ee\'e1\'ed\'ee\'e2\'eb\'e5\'ed\'e8\'e8 \'f8\'e0\'f0\'fb (\'f1\'ef\'e0\'f1\'e8\'e1\'ee Woldemar)\par \pard\lang1033\b\f1\fs20 ===\lang1049\f0 \lang1033\f1 r50\lang1049\f0 4 \lang1033\f1 build 21328 ===\par \pard\nowidctlpar\lang1049\b0\f0\fs16 * \'c8\'f1\'ef\'f0\'e0\'e2\'eb\'e5\'ed\'ee \'ea\'ee\'ef\'e8\'f0\'ee\'e2\'e0\'ed\'e8\'e5 torrent \'f1\'f1\'fb\'eb\'ea\'e8 \'e8\'e7 \'ee\'ea\'ed\'e0 \'ef\'e5\'f0\'e5\'e4\'e0\'f7\'e8. (balarama)\par diff --git a/jsoncpp/include/json/json.h b/jsoncpp/include/json/json.h index 141759708..09c6e6471 100644 --- a/jsoncpp/include/json/json.h +++ b/jsoncpp/include/json/json.h @@ -198,7 +198,7 @@ license you like. // In c++11 the override keyword allows you to explicitly define that a function // is intended to override the base-class version. This makes the code more -// managable and fixes a set of common hard-to-find bugs. +// manageable and fixes a set of common hard-to-find bugs. #if __cplusplus >= 201103L # define JSONCPP_OVERRIDE override # define JSONCPP_NOEXCEPT noexcept @@ -1944,7 +1944,7 @@ class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { * * The JSON document is written in a single line. It is not intended for 'human' *consumption, - * but may be usefull to support feature such as RPC where bandwith is limited. + * but may be useful to support feature such as RPC where bandwidth is limited. * \sa Reader, Value * \deprecated Use StreamWriterBuilder. */ diff --git a/jsoncpp/jsoncpp.cpp b/jsoncpp/jsoncpp.cpp index 46d74b581..e792e8aee 100644 --- a/jsoncpp/jsoncpp.cpp +++ b/jsoncpp/jsoncpp.cpp @@ -3653,7 +3653,12 @@ bool Value::removeMember(const char* key, const char* cend, Value* removed) ObjectValues::iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) return false; - *removed = it->second; + if (removed) +#if JSON_HAS_RVALUE_REFERENCES + *removed = std::move(it->second); +#else + *removed = it->second; +#endif value_.map_->erase(it); return true; } @@ -4365,7 +4370,7 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) { if (e - s < 4) return REPLACEMENT_CHARACTER; - unsigned int calculated = ((firstByte & 0x07) << 24) + unsigned int calculated = ((firstByte & 0x07) << 18) | ((static_cast(s[1]) & 0x3F) << 12) | ((static_cast(s[2]) & 0x3F) << 6) | (static_cast(s[3]) & 0x3F); diff --git a/libtorrent/ChangeLog b/libtorrent/ChangeLog index 6ede65b45..963bf2261 100644 --- a/libtorrent/ChangeLog +++ b/libtorrent/ChangeLog @@ -82,6 +82,10 @@ * resume data no longer has timestamps of files * require C++11 to build libtorrent + * defer truncating existing files until the first time we write to them + * fix issue when receiving a torrent with 0-sized padfiles as magnet link + * fix issue resuming 1.0.x downloads with a file priority 0 + * fix torrent_status::next_announce * fix pad-file scalability issue * made coalesce_reads/coalesce_writes settings take effect on linux and windows * restore support for incoming connections over SOCKS5 (disabled by default) diff --git a/libtorrent/include/libtorrent/aux_/session_impl.hpp b/libtorrent/include/libtorrent/aux_/session_impl.hpp index 5f69df41c..529ad0033 100644 --- a/libtorrent/include/libtorrent/aux_/session_impl.hpp +++ b/libtorrent/include/libtorrent/aux_/session_impl.hpp @@ -209,9 +209,9 @@ namespace aux { struct TORRENT_EXTRA_EXPORT listen_endpoint_t { - listen_endpoint_t(address adr, int p, std::string dev, transport s + listen_endpoint_t(address const& adr, int p, std::string dev, transport s , duplex d = duplex::accept_incoming) - : addr(adr), port(p), device(dev), ssl(s), incoming(d) {} + : addr(adr), port(p), device(std::move(dev)), ssl(s), incoming(d) {} bool operator==(listen_endpoint_t const& o) const { @@ -289,7 +289,7 @@ namespace aux { struct session_plugin_wrapper : plugin { - explicit session_plugin_wrapper(ext_function_t const& f) : m_f(f) {} + explicit session_plugin_wrapper(ext_function_t f) : m_f(std::move(f)) {} std::shared_ptr new_torrent(torrent_handle const& t, void* user) override { return m_f(t, user); } @@ -592,7 +592,6 @@ namespace aux { void get_cache_info(torrent_handle h, cache_status* ret, int flags) const; - void set_key(std::uint32_t key); std::uint16_t listen_port() const override; std::uint16_t listen_port(listen_socket_t* sock) const; std::uint16_t ssl_listen_port() const override; @@ -659,9 +658,6 @@ namespace aux { void deferred_submit_jobs() override; - torrent_peer* allocate_peer_entry(int type); - void free_peer_entry(torrent_peer* p); - // implements dht_observer void set_external_address(aux::listen_socket_handle const& iface , address const& ip, address const& source) override; @@ -788,7 +784,7 @@ namespace aux { void on_lsd_peer(tcp::endpoint const& peer, sha1_hash const& ih) override; void set_external_address(std::shared_ptr const& sock, address const& ip - , ip_source_t const source_type, address const& source); + , ip_source_t source_type, address const& source); void interface_to_endpoints(std::string const& device, int port , transport ssl, duplex incoming, std::vector& eps); diff --git a/libtorrent/include/libtorrent/block_cache.hpp b/libtorrent/include/libtorrent/block_cache.hpp index 5720beb7c..dc8fee7e7 100644 --- a/libtorrent/include/libtorrent/block_cache.hpp +++ b/libtorrent/include/libtorrent/block_cache.hpp @@ -188,7 +188,7 @@ namespace aux { return refcount == 0 && piece_refcount == 0 && !hashing - && read_jobs.size() == 0 + && read_jobs.empty() && outstanding_read == 0 && (ignore_hash || !hash || hash->offset == 0); } diff --git a/libtorrent/include/libtorrent/config.hpp b/libtorrent/include/libtorrent/config.hpp index dde4b569c..edf415b1e 100644 --- a/libtorrent/include/libtorrent/config.hpp +++ b/libtorrent/include/libtorrent/config.hpp @@ -35,13 +35,13 @@ POSSIBILITY OF SUCH DAMAGE. // [+]FlylinkDC++ #ifndef TORRENT_NO_BLOCK_ALERTS -#define TORRENT_NO_BLOCK_ALERTS +//#define TORRENT_NO_BLOCK_ALERTS #endif #ifndef TORRENT_NO_PIECE_ALERTS -#define TORRENT_NO_PIECE_ALERTS +//#define TORRENT_NO_PIECE_ALERTS #endif #ifndef TORRENT_NO_STATE_CHANGES_ALERTS -#define TORRENT_NO_STATE_CHANGES_ALERTS +//#define TORRENT_NO_STATE_CHANGES_ALERTS #endif #ifndef TORRENT_NO_DEPRECATE #define TORRENT_NO_DEPRECATE @@ -331,6 +331,7 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_USE_ICONV #define TORRENT_USE_ICONV 0 #endif +#define TORRENT_USE_MEMALIGN 1 // ==== GNU/Hurd === #elif defined __GNU__ diff --git a/libtorrent/include/libtorrent/disk_interface.hpp b/libtorrent/include/libtorrent/disk_interface.hpp index 8630743b0..559ce4a45 100644 --- a/libtorrent/include/libtorrent/disk_interface.hpp +++ b/libtorrent/include/libtorrent/disk_interface.hpp @@ -105,7 +105,7 @@ namespace libtorrent { } // this contains information about a file that's currently open by the - // libtorrent disk I/O subsystem. It's associated with a single torent. + // libtorrent disk I/O subsystem. It's associated with a single torrent. struct TORRENT_EXPORT open_file_state { // the index of the file this entry refers to into the ``file_storage`` diff --git a/libtorrent/include/libtorrent/disk_io_job.hpp b/libtorrent/include/libtorrent/disk_io_job.hpp index 463d1a711..51446db6c 100644 --- a/libtorrent/include/libtorrent/disk_io_job.hpp +++ b/libtorrent/include/libtorrent/disk_io_job.hpp @@ -137,10 +137,10 @@ namespace libtorrent { using read_handler = std::function; using write_handler = std::function; using hash_handler = std::function; - using move_handler = std::function; + using move_handler = std::function; using release_handler = std::function; using check_handler = std::function; - using rename_handler = std::function; + using rename_handler = std::function; using clear_piece_handler = std::function; boost::variant message_callback; + using message_callback = std::function; direct_traversal(node& node , node_id const& target , message_callback cb) : traversal_algorithm(node, target) - , m_cb(cb) + , m_cb(std::move(cb)) {} char const* name() const override { return "direct_traversal"; } diff --git a/libtorrent/include/libtorrent/kademlia/put_data.hpp b/libtorrent/include/libtorrent/kademlia/put_data.hpp index 3ff3d07a3..0bd985556 100644 --- a/libtorrent/include/libtorrent/kademlia/put_data.hpp +++ b/libtorrent/include/libtorrent/kademlia/put_data.hpp @@ -72,9 +72,9 @@ struct put_data_observer : traversal_observer { put_data_observer( std::shared_ptr algorithm - , udp::endpoint const& ep, node_id const& id, std::string const& token) + , udp::endpoint const& ep, node_id const& id, std::string token) : traversal_observer(std::move(algorithm), ep, id) - , m_token(token) + , m_token(std::move(token)) { } diff --git a/libtorrent/include/libtorrent/kademlia/routing_table.hpp b/libtorrent/include/libtorrent/kademlia/routing_table.hpp index fd06946be..6089cce0d 100644 --- a/libtorrent/include/libtorrent/kademlia/routing_table.hpp +++ b/libtorrent/include/libtorrent/kademlia/routing_table.hpp @@ -130,16 +130,6 @@ struct ip_set // bucket has failed, then it is put in the replacement // cache (just like in the paper). -namespace impl -{ - template - inline void forwarder(void* userdata, node_entry const& node) - { - F* f = reinterpret_cast(userdata); - (*f)(node); - } -} - TORRENT_EXTRA_EXPORT bool compare_ip_cidr(address const& lhs, address const& rhs); class TORRENT_EXTRA_EXPORT routing_table diff --git a/libtorrent/include/libtorrent/packet_pool.hpp b/libtorrent/include/libtorrent/packet_pool.hpp index 4900db441..21c30861f 100644 --- a/libtorrent/include/libtorrent/packet_pool.hpp +++ b/libtorrent/include/libtorrent/packet_pool.hpp @@ -130,6 +130,7 @@ namespace libtorrent { } packet_slab(const packet_slab&) = delete; + packet_slab(packet_slab&&) = default; void try_push_back(packet_ptr &p) { @@ -183,7 +184,7 @@ namespace libtorrent { { TORRENT_ASSERT(is_single_thread()); - if (p.get() == nullptr) return; + if (!p) return; int const allocated = p->allocated; diff --git a/libtorrent/include/libtorrent/peer_connection.hpp b/libtorrent/include/libtorrent/peer_connection.hpp index 8096447f0..1e8e0012a 100644 --- a/libtorrent/include/libtorrent/peer_connection.hpp +++ b/libtorrent/include/libtorrent/peer_connection.hpp @@ -155,11 +155,11 @@ namespace aux { std::weak_ptr t , aux::session_interface& ses , aux::session_settings const& sett) - : m_torrent(t) + : m_torrent(std::move(t)) , m_ses(ses) , m_settings(sett) , m_disconnecting(false) - , m_connecting(!t.expired()) + , m_connecting(!m_torrent.expired()) , m_endgame_mode(false) , m_snubbed(false) , m_interesting(false) @@ -442,8 +442,6 @@ namespace aux { // is called once every second by the main loop void second_tick(int tick_interval_ms); - void timeout_requests(); - std::shared_ptr get_socket() const { return m_socket; } tcp::endpoint const& remote() const override { return m_remote; } tcp::endpoint local_endpoint() const override { return m_local; } @@ -473,11 +471,6 @@ namespace aux { // finish the connection attempt bool is_connecting() const { return m_connecting; } - // This is called for every peer right after the upload - // bandwidth has been distributed among them - // It will reset the used bandwidth to 0. - void reset_upload_quota(); - // trust management. virtual void received_valid_data(piece_index_t index); // returns false if the peer should not be @@ -653,7 +646,7 @@ namespace aux { bool piece_failed; #endif - time_t last_seen_complete() const { return m_last_seen_complete; } + std::time_t last_seen_complete() const { return m_last_seen_complete; } void set_last_seen_complete(int ago) { m_last_seen_complete = ::time(nullptr) - ago; } std::int64_t uploaded_in_last_round() const @@ -844,10 +837,6 @@ namespace aux { #endif private: - // the average rate of receiving complete piece messages - sliding_average<20> m_piece_rate; - sliding_average<20> m_send_rate; - // the average time between incoming pieces. Or, if there is no // outstanding request, the time since the piece was requested. It // is essentially an estimate of the time it will take to completely @@ -983,10 +972,6 @@ namespace aux { // remote peer's id peer_id m_peer_id; - // the bandwidth channels, upload and download - // keeps track of the current quotas - bandwidth_channel m_bandwidth_channel[num_channels]; - protected: template diff --git a/libtorrent/include/libtorrent/sha1_hash.hpp b/libtorrent/include/libtorrent/sha1_hash.hpp index 172f6d046..ba479ecef 100644 --- a/libtorrent/include/libtorrent/sha1_hash.hpp +++ b/libtorrent/include/libtorrent/sha1_hash.hpp @@ -64,7 +64,7 @@ namespace aux { // // This data structure is 32 bits aligned, like it's the case for // each SHA-N specification. - template + template class digest32 { static_assert(N % 32 == 0, "N must be a multiple of 32"); diff --git a/libtorrent/include/libtorrent/sliding_average.hpp b/libtorrent/include/libtorrent/sliding_average.hpp index 14174057c..068b27813 100644 --- a/libtorrent/include/libtorrent/sliding_average.hpp +++ b/libtorrent/include/libtorrent/sliding_average.hpp @@ -83,35 +83,6 @@ struct sliding_average int m_num_samples = 0; }; -struct average_accumulator -{ - average_accumulator() {} - - void add_sample(std::int64_t s) - { - ++m_num_samples; - m_sample_sum += s; - } - - int mean() - { - int ret; - if (m_num_samples == 0) ret = 0; - else ret = int(m_sample_sum / m_num_samples); - // in case we don't get any more samples, at least - // let the average roll over, but only be worth a - // single sample - m_num_samples = 1; - m_sample_sum = ret; - return ret; - } - -private: - - int m_num_samples = 0; - std::int64_t m_sample_sum = 0; -}; - } #endif diff --git a/libtorrent/include/libtorrent/storage.hpp b/libtorrent/include/libtorrent/storage.hpp index 30e0b622b..9b9a3a550 100644 --- a/libtorrent/include/libtorrent/storage.hpp +++ b/libtorrent/include/libtorrent/storage.hpp @@ -366,7 +366,7 @@ namespace libtorrent { // the file_storage object is owned by the torrent. std::shared_ptr m_torrent; - storage_index_t m_storage_index; + storage_index_t m_storage_index{0}; // the number of block_cache_reference objects referencing this storage std::atomic m_references{1}; @@ -425,8 +425,6 @@ namespace libtorrent { private: - void delete_one_file(std::string const& p, error_code& ec); - void need_partfile(); std::unique_ptr m_mapped_files; @@ -444,6 +442,14 @@ namespace libtorrent { aux::vector m_file_priority; std::string m_save_path; std::string m_part_file_name; + + // if this is false, we're not using a part file to store priority-0 + // pieces, but we instead look for them under their actual file names + // this defaults to true, but when checking resume data for a torrent + // where we would expect to have a part file, but there isn't one, we set + // this to false. + bool m_use_part_file = true; + // the file pool is a member of the disk_io_thread // to make all storage instances share the pool file_pool& m_pool; diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index 00ab961b8..f0466adf2 100644 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -109,7 +109,6 @@ namespace libtorrent { struct add_torrent_params; struct storage_interface; class bt_peer_connection; - struct listen_socket_t; peer_id generate_peer_id(aux::session_settings const& sett); @@ -600,7 +599,7 @@ namespace libtorrent { int priority() const; #ifndef TORRENT_NO_DEPRECATE - void set_priority(int const prio); + void set_priority(int prio); #endif // TORRENT_NO_DEPRECATE // -------------------------------------------- @@ -747,10 +746,6 @@ namespace libtorrent { // immediately void do_connect_boost(); - // returns the absolute time when the next tracker - // announce will take place. - time_point next_announce() const; - // forcefully sets next_announce to the current time void force_tracker_request(time_point, int tracker_idx); void scrape_tracker(int idx, bool user_triggered); @@ -1177,7 +1172,7 @@ namespace libtorrent { void on_storage_moved(status_t status, std::string const& path , storage_error const& error); void on_file_renamed(std::string const& filename - , file_index_t const file_idx + , file_index_t file_idx , storage_error const& error); void on_cache_flushed(); @@ -1192,8 +1187,6 @@ namespace libtorrent { int prioritize_tracker(int tracker_index); int deprioritize_tracker(int tracker_index); - bool request_bandwidth_from_session(int channel) const; - void update_peer_interest(bool was_finished); void prioritize_udp_trackers(); @@ -1614,12 +1607,6 @@ namespace libtorrent { // the DHT bool m_announce_to_dht:1; - // these represent whether or not this torrent is counted - // in the total counters of active seeds and downloads - // in the session. - bool m_is_active_download:1; - bool m_is_active_finished:1; - // even if we're not built to support SSL torrents, // remember that this is an SSL torrent, so that we don't // accidentally start seeding it without any authentication. diff --git a/libtorrent/include/libtorrent/torrent_info.hpp b/libtorrent/include/libtorrent/torrent_info.hpp index d38e3a6e2..5820c9f32 100644 --- a/libtorrent/include/libtorrent/torrent_info.hpp +++ b/libtorrent/include/libtorrent/torrent_info.hpp @@ -163,7 +163,7 @@ namespace libtorrent { explicit torrent_info(span buffer, from_span_t); explicit torrent_info(std::string const& filename); #endif // BOOST_NO_EXCEPTIONS - explicit torrent_info(torrent_info const& t); + torrent_info(torrent_info const& t); explicit torrent_info(sha1_hash const& info_hash); torrent_info(bdecode_node const& torrent_file, error_code& ec); torrent_info(char const* buffer, int size, error_code& ec) diff --git a/libtorrent/include/libtorrent/tracker_manager.hpp b/libtorrent/include/libtorrent/tracker_manager.hpp index 2f353bf24..ac8b01c52 100644 --- a/libtorrent/include/libtorrent/tracker_manager.hpp +++ b/libtorrent/include/libtorrent/tracker_manager.hpp @@ -85,9 +85,6 @@ namespace libtorrent { #endif namespace aux { struct session_logger; struct session_settings; } - // returns -1 if gzip header is invalid or the header size in bytes - TORRENT_EXTRA_EXPORT int gzip_header(const char* buf, int size); - struct TORRENT_EXTRA_EXPORT tracker_request { tracker_request() @@ -103,9 +100,6 @@ namespace libtorrent { , num_want(0) , private_torrent(false) , triggered_manually(false) -#ifdef TORRENT_USE_OPENSSL - , ssl_ctx(0) -#endif {} enum event_t @@ -167,7 +161,7 @@ namespace libtorrent { bool triggered_manually; #ifdef TORRENT_USE_OPENSSL - boost::asio::ssl::context* ssl_ctx; + boost::asio::ssl::context* ssl_ctx = nullptr; #endif #if TORRENT_USE_I2P i2p_connection* i2pconn = nullptr; diff --git a/libtorrent/include/libtorrent/udp_tracker_connection.hpp b/libtorrent/include/libtorrent/udp_tracker_connection.hpp index 50af5de96..6ba8c0326 100644 --- a/libtorrent/include/libtorrent/udp_tracker_connection.hpp +++ b/libtorrent/include/libtorrent/udp_tracker_connection.hpp @@ -84,7 +84,6 @@ namespace libtorrent { void name_lookup(error_code const& error , std::vector
const& addresses, int port); - void timeout(error_code const& error); void start_announce(); bool on_receive(udp::endpoint const& ep, span buf); diff --git a/libtorrent/src/allocator.cpp b/libtorrent/src/allocator.cpp index a4f5f1166..0db3d3bde 100644 --- a/libtorrent/src/allocator.cpp +++ b/libtorrent/src/allocator.cpp @@ -35,10 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/assert.hpp" // for print_backtrace #include -#if defined TORRENT_BEOS -#include -#include // malloc/free -#elif !defined TORRENT_WINDOWS +#if !defined TORRENT_WINDOWS #include // posix_memalign/free #include // _SC_PAGESIZE #endif @@ -119,10 +116,6 @@ namespace libtorrent { ret = ::memalign(std::size_t(page_size()), std::size_t(bytes)); #elif defined TORRENT_WINDOWS ret = ::_aligned_malloc(std::size_t(bytes), std::size_t(page_size())); -#elif defined TORRENT_BEOS - area_id id = create_area("", &ret, B_ANY_ADDRESS - , (bytes + page_size() - 1) & (page_size() - 1), B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (id < B_OK) return nullptr; #else ret = valloc(std::size_t(bytes)); #endif @@ -188,10 +181,6 @@ namespace libtorrent { #ifdef TORRENT_WINDOWS _aligned_free(block); -#elif defined TORRENT_BEOS - area_id id = area_for(block); - if (id < B_OK) return; - delete_area(id); #else ::free(block); #endif // TORRENT_WINDOWS diff --git a/libtorrent/src/bt_peer_connection.cpp b/libtorrent/src/bt_peer_connection.cpp index 10372872b..5d82c94d8 100644 --- a/libtorrent/src/bt_peer_connection.cpp +++ b/libtorrent/src/bt_peer_connection.cpp @@ -851,7 +851,7 @@ namespace { // m_outstanding_bytes if (r.piece == t->torrent_file().last_piece()) { - r.length = (std::min)(t->torrent_file().piece_size( + r.length = std::min(t->torrent_file().piece_size( r.piece) - r.start, r.length); } incoming_reject_request(r); @@ -1179,8 +1179,8 @@ namespace { || e.list_at(1).type() != bdecode_node::string_t || e.list_at(1).string_length() != 20) continue; - nodes.insert(std::make_pair(int(e.list_int_value_at(0)) - , sha1_hash(e.list_at(1).string_ptr()))); + nodes.emplace(int(e.list_int_value_at(0)) + , sha1_hash(e.list_at(1).string_ptr())); } if (!nodes.empty() && !t->add_merkle_nodes(nodes, p.piece)) { @@ -1948,7 +1948,7 @@ namespace { // Don't require the bitfield to have been sent at this point // the case where m_sent_bitfield may not be true is if the - // torrent doesn't have any metadata, and a peer is timimg out. + // torrent doesn't have any metadata, and a peer is timing out. // then the keep-alive message will be sent before the bitfield // this is a violation to the original protocol, but necessary // for the metadata extension. @@ -2321,9 +2321,9 @@ namespace { l.reserve(merkle_node_list.size()); for (auto const& i : merkle_node_list) { - l.push_back(entry(entry::list_t)); - l.back().list().push_back(i.first); - l.back().list().push_back(i.second.to_string()); + l.emplace_back(entry::list_t); + l.back().list().emplace_back(i.first); + l.back().list().emplace_back(i.second.to_string()); } bencode(std::back_inserter(piece_list_buf), piece_list); detail::write_int32(int(piece_list_buf.size()), ptr); @@ -2763,7 +2763,7 @@ namespace { // otherwise keep the least significant one if (m_settings.get_bool(settings_pack::prefer_rc4)) { - std::uint32_t mask = (std::numeric_limits::max)(); + std::uint32_t mask = std::numeric_limits::max(); while (crypto_select & (mask << 1)) { mask <<= 1; @@ -2772,7 +2772,7 @@ namespace { } else { - std::uint32_t mask = (std::numeric_limits::max)(); + std::uint32_t mask = std::numeric_limits::max(); while (crypto_select & (mask >> 1)) { mask >>= 1; diff --git a/libtorrent/src/disk_io_thread.cpp b/libtorrent/src/disk_io_thread.cpp index 6eafc45c9..6063c268a 100644 --- a/libtorrent/src/disk_io_thread.cpp +++ b/libtorrent/src/disk_io_thread.cpp @@ -1698,6 +1698,7 @@ constexpr disk_job_flags_t disk_interface::cache_hit; { TORRENT_ASSERT(r.length <= default_block_size); TORRENT_ASSERT(r.length <= 16 * 1024); + TORRENT_ASSERT(buf != nullptr); bool exceeded = false; disk_buffer_holder buffer(*this, m_disk_cache.allocate_buffer(exceeded, o, "receive buffer"), 0x4000); diff --git a/libtorrent/src/enum_net.cpp b/libtorrent/src/enum_net.cpp index 02d877a6c..0eb26fe61 100644 --- a/libtorrent/src/enum_net.cpp +++ b/libtorrent/src/enum_net.cpp @@ -790,7 +790,7 @@ int _System __libsocket_sysctl(int* mib, u_int namelen, void *oldp, size_t *oldl udp::resolver::iterator i = r.resolve(udp::resolver::query(boost::asio::ip::host_name(ec), "0"), ec); if (ec) return ret; ip_interface iface; - for (;i != udp::resolver_iterator(); ++i) + for (;i != udp::resolver::iterator(); ++i) { iface.interface_address = i->endpoint().address(); iface.name[0] = '\0'; @@ -815,6 +815,7 @@ int _System __libsocket_sysctl(int* mib, u_int namelen, void *oldp, size_t *oldl { std::vector ret; TORRENT_UNUSED(ios); + TORRENT_UNUSED(ec); #ifdef TORRENT_BUILD_SIMULATOR diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index e1190dd30..698a4239b 100644 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -6236,7 +6236,7 @@ namespace aux { template void set_tos(Socket& s, int v, error_code& ec) { -#if TORRENT_USE_IPV6 +#if TORRENT_USE_IPV6 && defined IPV6_TCLASS if (s.local_endpoint(ec).address().is_v6()) s.set_option(traffic_class(char(v)), ec); else if (!ec) diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index a5719a939..0c907de61 100644 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -239,9 +239,9 @@ namespace libtorrent { // ignore pad files if (files().pad_file_at(file_index)) continue; + // this is just to see if the file exists error_code err; - std::int64_t size = m_stat_cache.get_filesize(file_index, files() - , m_save_path, err); + m_stat_cache.get_filesize(file_index, files(), m_save_path, err); if (err && err != boost::system::errc::no_such_file_or_directory) { @@ -251,11 +251,12 @@ namespace libtorrent { break; } - // if the file already exists, but is larger than what - // it's supposed to be, truncate it - // if the file is empty, just create it either way. - if ((!err && size > files().file_size(file_index)) - || (files().file_size(file_index) == 0 && err == boost::system::errc::no_such_file_or_directory)) + // if the file is empty and doesn't already exist, create it + // deliberately don't truncate files that already exist + // if a file is supposed to have size 0, but already exists, we will + // never truncate it to 0. + if (files().file_size(file_index) == 0 + && err == boost::system::errc::no_such_file_or_directory) { std::string file_path = files().file_path(file_index, m_save_path); std::string dir = parent_path(file_path); @@ -273,23 +274,12 @@ namespace libtorrent { } } ec.ec.clear(); + // just creating the file is enough to make it zero-sized. If + // there's a race here and some other process truncates the file, + // it's not a problem, we won't access empty files ever again file_handle f = open_file(file_index, open_mode::read_write | open_mode::random_access, ec); - if (ec) - { - ec.file(file_index); - ec.operation = operation_t::file_fallocate; - return; - } - - size = files().file_size(file_index); - f->set_size(size, ec.ec); - if (ec) - { - ec.file(file_index); - ec.operation = operation_t::file_fallocate; - break; - } + if (ec) return; } ec.ec.clear(); } @@ -469,7 +459,8 @@ namespace libtorrent { } if (file_index < m_file_priority.end_index() - && m_file_priority[file_index] == dont_download) + && m_file_priority[file_index] == dont_download + && m_use_part_file) { TORRENT_ASSERT(m_part_file); //need_partfile(); // try fix https://github.com/arvidn/libtorrent/issues/2489 @@ -533,7 +524,8 @@ namespace libtorrent { } if (file_index < m_file_priority.end_index() - && m_file_priority[file_index] == dont_download) + && m_file_priority[file_index] == dont_download + && m_use_part_file) { TORRENT_ASSERT(m_part_file); //need_partfile(); // try fix https://github.com/arvidn/libtorrent/issues/2489 @@ -617,7 +609,7 @@ namespace libtorrent { } TORRENT_ASSERT(h); - if (m_allocate_files && (mode & open_mode::rw_mask) != open_mode::read_only) + if ((mode & open_mode::rw_mask) != open_mode::read_only) { std::unique_lock l(m_file_created_mutex); if (m_file_created.size() != files().num_files()) @@ -632,9 +624,12 @@ namespace libtorrent { { m_file_created.set_bit(file); l.unlock(); - error_code e; + + // if we're allocating files or if the file exists and is greater + // than what it's supposed to be, truncate it to its correct size std::int64_t const size = files().file_size(file); - h->set_size(size, e); + error_code e; + bool const need_truncate = h->get_size(e) > size; if (e) { ec.ec = e; @@ -642,7 +637,19 @@ namespace libtorrent { ec.operation = operation_t::file_fallocate; return h; } - m_stat_cache.set_dirty(file); + + if (m_allocate_files || need_truncate) + { + h->set_size(size, e); + if (e) + { + ec.ec = e; + ec.file(file); + ec.operation = operation_t::file_fallocate; + return h; + } + m_stat_cache.set_dirty(file); + } } } return h; diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index b8a5e380a..074299a97 100644 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -200,8 +200,6 @@ namespace libtorrent { , m_padding(0) , m_incomplete(0xffffff) , m_announce_to_dht(!(p.flags & torrent_flags::paused)) - , m_is_active_download(false) - , m_is_active_finished(false) , m_ssl_torrent(false) , m_deleted(false) , m_auto_managed(p.flags & torrent_flags::auto_managed) @@ -1780,6 +1778,8 @@ namespace libtorrent { } else { + need_picker(); + int num_pad_files = 0; TORRENT_ASSERT(block_size() > 0); @@ -1790,10 +1790,6 @@ namespace libtorrent { if (!fs.pad_file_at(i) || fs.file_size(i) == 0) continue; m_padding += std::uint32_t(fs.file_size(i)); - // TODO: instead of creating the picker up front here, - // maybe this whole section should move to need_picker() - need_picker(); - peer_request pr = m_torrent_file->map_file(i, 0, int(fs.file_size(i))); int off = pr.start & (block_size() - 1); if (off != 0) { pr.length -= block_size() - off; pr.start += block_size() - off; } @@ -3326,11 +3322,6 @@ namespace libtorrent { if (want_peers()) m_ses.prioritize_connections(shared_from_this()); } - time_point torrent::next_announce() const - { - return m_waiting_tracker ? m_tracker_timer.expires_at() : min_time(); - } - // this is the entry point for the client to force a re-announce. It's // considered a client-initiated announce (as opposed to the regular ones, // issued by libtorrent) @@ -10723,10 +10714,10 @@ namespace { st->download_payload_rate = m_stat.download_payload_rate(); st->upload_payload_rate = m_stat.upload_payload_rate(); - if (m_waiting_tracker && !is_paused()) - st->next_announce = next_announce() - now; - else + if (is_paused() || m_tracker_timer.expires_at() < now) st->next_announce = seconds(0); + else + st->next_announce = m_tracker_timer.expires_at() - now; if (st->next_announce.count() < 0) st->next_announce = seconds(0); diff --git a/libtorrent/src/torrent_peer.cpp b/libtorrent/src/torrent_peer.cpp index 222964acb..a363bbec4 100644 --- a/libtorrent/src/torrent_peer.cpp +++ b/libtorrent/src/torrent_peer.cpp @@ -36,8 +36,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/peer_connection.hpp" #include "libtorrent/crc32c.hpp" #include "libtorrent/ip_voter.hpp" - -#include // for BIG_ENDIAN and LITTLE_ENDIAN macros +#include "libtorrent/io.hpp" // for write_uint16 namespace libtorrent { @@ -84,15 +83,9 @@ namespace libtorrent { if (e1.port() > e2.port()) swap(e1, e2); std::uint32_t p; -#if defined BOOST_BIG_ENDIAN - p = std::uint32_t(e1.port() << 16); - p |= e2.port(); -#elif defined BOOST_LITTLE_ENDIAN - p = std::uint32_t(aux::host_to_network(e2.port()) << 16); - p |= aux::host_to_network(e1.port()); -#else -#error unsupported endianness -#endif + auto ptr = reinterpret_cast(&p); + detail::write_uint16(e1.port(), ptr); + detail::write_uint16(e2.port(), ptr); ret = crc32c_32(p); } #if TORRENT_USE_IPV6 diff --git a/revision.h b/revision.h index 3f369453b..d0681699f 100644 --- a/revision.h +++ b/revision.h @@ -2,7 +2,7 @@ #define FLY_REVISION_H #define VERSION_NUM 504 -#define REVISION_NUM 21332 +#define REVISION_NUM 21352 //#define FLYLINKDC_BETA #define BETA_NUM // Number of beta. Does not matter if the #define FLYLINKDC_BETA is disabled. diff --git a/windows/SearchFrm.cpp b/windows/SearchFrm.cpp index 0a488163c..782510f44 100644 --- a/windows/SearchFrm.cpp +++ b/windows/SearchFrm.cpp @@ -298,58 +298,58 @@ LRESULT SearchFrame::onCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam* fixme:dbghelp:MiniDumpWriteDump NIY MiniDumpWithFullMemory fixme:edit:EDIT_EM_FmtLines soft break enabled, not implemented */ -/* +#ifdef FLYLINKDC_USE_TORRENT_PANEL { - CRect rcVert; - GetClientRect(&rcVert); - - // create the vertical splitter - m_vSplit.Create(m_hWnd, rcVert, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); - - // set the vertical splitter parametersf - m_vSplit.m_cxyMin = 222; // minimum size - m_vSplit.SetSplitterPos(222); // from left - //m_vSplit.m_bFullDrag = false; // ghost bar enabled - - CRect rcHorz; - GetClientRect(&rcHorz); - - // create the horizontal splitter. Note that vSplit is parent of hzSplit - m_hzSplit.Create(m_vSplit, rcHorz, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); - - // set the horizontal splitter parameters - m_hzSplit.m_cxyMin = 35; // minimum size - m_hzSplit.SetSplitterPos(100); // from top - m_hzSplit.m_bFullDrag = false; // ghost bar enabled - - // add the horizontal splitter to right pane of vertical splitter - m_vSplit.SetSplitterPane(1, m_hzSplit); - m_lPane.Create(m_vSplit.m_hWnd); - // add container to left pane (0) of vertical splitter - m_vSplit.SetSplitterPane(0, m_lPane); - - // set the left pane title - //m_lPane.SetTitle(_T("Left Pane")); - //m_lPane.SetPaneContainerExtendedStyle(PANECNT_NOCLOSEBUTTON); - - // create the top container. Note use of hzSplit as parent - m_tPane.Create(m_hzSplit.m_hWnd); - - // add container to top pane (0) of horizontal splitter - m_hzSplit.SetSplitterPane(0, m_tPane); - - // set the top pane title - m_tPane.SetTitle(_T("Top Pane -- no Close button")); - - // remove the close button from the top container - m_tPane.SetPaneContainerExtendedStyle(PANECNT_NOCLOSEBUTTON); - - } -*/ -HWND l_lHwnd = m_hWnd; - -// HWND l_lHwnd = m_lPane; -// HWND l_SearchHwnd = m_tPane; + CRect rcVert; + GetClientRect(&rcVert); + + // create the vertical splitter + m_vSplit.Create(m_hWnd, rcVert, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + + // set the vertical splitter parametersf + m_vSplit.m_cxyMin = 222; // minimum size + m_vSplit.SetSplitterPos(222); // from left + //m_vSplit.m_bFullDrag = false; // ghost bar enabled + + CRect rcHorz; + GetClientRect(&rcHorz); + + // create the horizontal splitter. Note that vSplit is parent of hzSplit + m_hzSplit.Create(m_vSplit, rcHorz, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + + // set the horizontal splitter parameters + m_hzSplit.m_cxyMin = 35; // minimum size + m_hzSplit.SetSplitterPos(100); // from top + m_hzSplit.m_bFullDrag = false; // ghost bar enabled + + // add the horizontal splitter to right pane of vertical splitter + m_vSplit.SetSplitterPane(1, m_hzSplit); + m_lPane.Create(m_vSplit.m_hWnd); + // add container to left pane (0) of vertical splitter + m_vSplit.SetSplitterPane(0, m_lPane); + + // set the left pane title + //m_lPane.SetTitle(_T("Left Pane")); + //m_lPane.SetPaneContainerExtendedStyle(PANECNT_NOCLOSEBUTTON); + + // create the top container. Note use of hzSplit as parent + m_tPane.Create(m_hzSplit.m_hWnd); + + // add container to top pane (0) of horizontal splitter + m_hzSplit.SetSplitterPane(0, m_tPane); + + // set the top pane title + m_tPane.SetTitle(_T("Top Pane -- no Close button")); + + // remove the close button from the top container + m_tPane.SetPaneContainerExtendedStyle(PANECNT_NOCLOSEBUTTON); + + } + HWND l_lHwnd = m_lPane; + HWND l_SearchHwnd = m_tPane; +#else + HWND l_lHwnd = m_hWnd; +#endif m_tooltip.Create(m_hWnd, rcDefault, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP /*| TTS_BALLOON*/, WS_EX_TOPMOST); m_tooltip.SetDelayTime(TTDT_AUTOPOP, 15000); dcassert(m_tooltip.IsWindow()); @@ -398,7 +398,7 @@ HWND l_lHwnd = m_hWnd; } ctrlResults.m_is_managed = true; // m_tPane.SetClient(ctrlResults); - + #ifdef FLYLINKDC_USE_TREE_SEARCH m_ctrlSearchFilterTree.Create(l_lHwnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_DISABLEDRAGDROP, WS_EX_CLIENTEDGE, IDC_TRANSFER_TREE); m_ctrlSearchFilterTree.SetBkColor(Colors::g_bgColor); @@ -2561,7 +2561,9 @@ void SearchFrame::UpdateLayout(BOOL bResizeBars) #endif rc.left += width + l_width_tree; rc.bottom -= 26; - ctrlResults.MoveWindow(rc); + CRect rc_result = rc; + // TODO rc_result.bottom -= 100; + ctrlResults.MoveWindow(rc_result); #ifdef FLYLINKDC_USE_TREE_SEARCH if (m_is_use_tree) @@ -4160,7 +4162,10 @@ LRESULT SearchFrame::onCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled const string l_str_ip = Text::fromT(ip); si->m_location = Util::getIpCountry(l_str_ip); #ifdef FLYLINKDC_USE_LASTIP_AND_USER_RATIO - if (si->m_is_flush_ip_to_sqlite == false && m_storeIP && si->getUser()->getHubID()) + if (si->m_is_flush_ip_to_sqlite == false && + m_storeIP && + si->getUser() && // https://drdump.com/Problem.aspx?ProblemID=364805 + si->getUser()->getHubID()) { si->m_is_flush_ip_to_sqlite = true; boost::system::error_code ec; diff --git a/windows/SearchFrm.h b/windows/SearchFrm.h index ee90446b7..33fb57556 100644 --- a/windows/SearchFrm.h +++ b/windows/SearchFrm.h @@ -36,7 +36,7 @@ #include "../FlyFeatures/GradientLabel.h" #include "../FlyFeatures/flyServer.h" -//#include "wtlbuilder/Panel.h" +#include "wtlbuilder/Panel.h" //#ifdef _DEBUG #define FLYLINKDC_USE_TREE_SEARCH @@ -354,12 +354,17 @@ class SearchFrame : public MDITabChildWindowImpl < SearchFrame, RGB(127, 127, 25 { return ctrlResults; } - //CHorSplitterWindow m_hzSplit; - //CSplitterWindow m_vSplit; - //CPaneContainer m_lPane; - //CPaneContainer m_tPane; - - +#ifdef _DEBUG + #define FLYLINKDC_USE_TORRENT_PANEL +#endif +#ifdef FLYLINKDC_USE_TORRENT_PANEL + CHorSplitterWindow m_hzSplit; + CSplitterWindow m_vSplit; + CPaneContainer m_lPane; + CPaneContainer m_tPane; +#endif + + private: #ifdef FLYLINKDC_USE_ADVANCED_GRID_SEARCH /** time difference */ diff --git a/windows/TransferView.cpp b/windows/TransferView.cpp index 058afa41f..574c6acfd 100644 --- a/windows/TransferView.cpp +++ b/windows/TransferView.cpp @@ -265,7 +265,7 @@ LRESULT TransferView::onCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam m_copyTorrentMenu.CreatePopupMenu(); m_copyTorrentMenu.AppendMenu(MF_STRING, IDC_COPY_LINK, CTSTRING(COPY_MAGNET_LINK)); - + usercmdsMenu.CreatePopupMenu(); segmentedMenu.CreatePopupMenu(); @@ -2804,8 +2804,7 @@ LRESULT TransferView::onCopy(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, B l_data = Text::toT(DownloadManager::getInstance()->get_torrent_magnet(l_ii->m_sha1)); } } - else - if (getTTH(l_ii, l_tth)) + else if (getTTH(l_ii, l_tth)) { tstring l_sdata; if (wID == IDC_COPY_TTH) diff --git a/windows/wtlbuilder/CallBack.h b/windows/wtlbuilder/CallBack.h new file mode 100644 index 000000000..a11b1e234 --- /dev/null +++ b/windows/wtlbuilder/CallBack.h @@ -0,0 +1,106 @@ +#ifndef __CALLBACK__H +#define __CALLBACK__H +////////////////////////////////////////////////////////////////////////////////////////////////// +class CallBack +{ +public: + typedef void (CallBack::*CallBackMethod)(void); +protected: + CallBack *self; + CallBackMethod method; +public: + + CallBack(void):self(NULL),method(NULL) + { + } + + //CallBack(CallBack *s,CallBackMethod m):self(s),method(m) + //{ + //} + + CallBack(const CallBack & n):self(n.self),method(n.method) + { + } + + void operator ()(void) + { + if(self && method) + (self->*(method))(); + } + + template void operator ()(T1 par) + { + typedef void (CallBack::*CallBackMethod1)(T1); + if(self && method) + (self->*((CallBackMethod1)method))(par); + } + + template void operator ()(T1 par1,T2 par2) + { + typedef void (CallBack::*CallBackMethod2)(T1,T2); + if(self && method) + (self->*((CallBackMethod2)method))(par1,par2); + } + + template void operator ()(T1 par1,T2 par2,T3 par3) + { + typedef void (CallBack::*CallBackMethod3)(T1,T2,T3); + if(self && method) + (self->*((CallBackMethod3)method))(par1,par2,par3); + } + + template void SetObject(T *s ) + { + self=(CallBack *)(void*)s; + } + + template void SetMethod(T s) + { + method=(CallBackMethod&)s; + } + + operator CallBack *(void) + { + return self; + } + + operator CallBackMethod (void) + { + return method; + } + + CallBack & operator=(CallBack * s) + { + self=s; + return *this; + } + + CallBack & operator=(CallBackMethod m) + { + method=m; + return *this; + } + + CallBack & operator=(CallBack & n) + { + self=n.self; + method=n.method; + return *this; + } +}; +////////////////////////////////////////////////////////////////////////////////////////////////// +#define DECLARE_CALLBACK(Name,Var)\ +void Set##Name(CallBack & n)\ +{\ + Var=n;\ +}\ +CallBack & Get##Name(void)\ +{\ + return Var;\ +}\ +__declspec(property(get=Get##Name, put=Set##Name)) CallBack & Name;\ +protected:\ + CallBack Var;\ +public: +////////////////////////////////////////////////////////////////////////////////////////////////// +#endif \ No newline at end of file diff --git a/windows/wtlbuilder/GDIUtil.cpp b/windows/wtlbuilder/GDIUtil.cpp new file mode 100644 index 000000000..78478b7f3 --- /dev/null +++ b/windows/wtlbuilder/GDIUtil.cpp @@ -0,0 +1,1039 @@ +#include "stdafx.h" +#include "gdiutil.h" +#ifdef __WTLBUILDER__ +#include "..\iProperty\iProperty.h" +#include "..\iProperty\iPropertyListEdit.h" +#endif +//#include +////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// +//IMPLEMENT_NOTIFY(CPenEx,Notify,notify) +#ifdef __WTLBUILDER__ +typedef int PenStyle; +#endif + +//REGISTER_LIST_PROPERTY(Bold) +//REGISTER_LIST_PROPERTY(CharSet) +//REGISTER_LIST_PROPERTY(OutPrecision) +//REGISTER_LIST_PROPERTY(ClipPrecision) +//REGISTER_LIST_PROPERTY(Quality) + +//REGISTER_LIST_PROPERTY(BrushStyle) +//REGISTER_LIST_PROPERTY(BrushHatch) + + +CPenEx::CPenEx(void):handle(NULL) +{ + logpen.lopnStyle=PS_SOLID; + logpen.lopnWidth.x=1; + logpen.lopnColor=RGB(0,0,0); +} + +CPenEx::CPenEx(int style,int width,CColorref color) +{ + handle=CreatePen(style,width,color); + logpen.lopnStyle=style; + logpen.lopnWidth.x=width; + logpen.lopnColor=color; +} + +CPenEx::~CPenEx() +{ + if(handle) + DeleteObject(handle); +} + +void CPenEx::set_Style(int s) +{ + logpen.lopnStyle=s; + DeleteObject(handle); + handle=CreatePenIndirect(&logpen); + change(this); +} + +int CPenEx::get_Style(void) +{ + return logpen.lopnStyle; +} + +void CPenEx::set_Width(int w) +{ + logpen.lopnWidth.x=w; + DeleteObject(handle); + handle=CreatePenIndirect(&logpen); + change(this); +} + +int CPenEx::get_Width(void) +{ + return logpen.lopnWidth.x; +} + +void CPenEx::set_Color(CColorref c) +{ + logpen.lopnColor=c; + DeleteObject(handle); + handle=CreatePenIndirect(&logpen); + change(this); +} + +CColorref CPenEx::get_Color(void) +{ + return logpen.lopnColor; +} + +CPenEx::operator HPEN() +{ + return handle; +} +#ifdef __WTLBUILDER__ +void CPenEx::AddProperty(const char *Name,CProperties & objprop) +{ + BEGIN_CLASS_SUB_PROPERTY(Name,CPenEx) + DEFINE_SUB_PROPERTY(Style,PenStyle,CPenEx,PS_SOLID) + DEFINE_SUB_PROPERTY(Width,int,CPenEx,1) + DEFINE_SUB_PROPERTY(Color,CColorref,CPenEx,0) + END_CLASS_SUB_PROPERTY +} +#endif +//////////////////////////////////////////////////////////////////////////////////////////////// +//IMPLEMENT_NOTIFY(CBrushEx,Notify,notify) +CBrushEx::CBrushEx(void):handle(NULL) +{ + logbrush.lbStyle=BS_NULL; + logbrush.lbHatch=HS_BDIAGONAL; + logbrush.lbColor=RGB(0xFF,0xFF,0xFF); +} + +CBrushEx::CBrushEx(int style,int hatch,CColorref color) +{ + logbrush.lbStyle=style; + logbrush.lbHatch=hatch; + logbrush.lbColor=color; + handle=CreateBrushIndirect(&logbrush); +} + +CBrushEx::CBrushEx(CColorref color) +{ + logbrush.lbStyle=BS_SOLID; + logbrush.lbHatch=0; + logbrush.lbColor=color; + handle=CreateBrushIndirect(&logbrush); +} + +CBrushEx::~CBrushEx() +{ + if(handle) + DeleteObject(handle); +} + +void CBrushEx::set_Style(long s) +{ + logbrush.lbStyle=s; + DeleteObject(handle); + handle=CreateBrushIndirect(&logbrush); + change(this); +} + +long CBrushEx::get_Style(void) +{ + return logbrush.lbStyle; +} + +void CBrushEx::set_Hatch(long h) +{ + logbrush.lbHatch=h; + DeleteObject(handle); + handle=CreateBrushIndirect(&logbrush); + change(this); +} + +long CBrushEx::get_Hatch(void) +{ + return (int)logbrush.lbHatch; +} + +void CBrushEx::set_Color(CColorref c) +{ + logbrush.lbColor=c; + DeleteObject(handle); + handle=CreateBrushIndirect(&logbrush); + change(this); +} + +CColorref CBrushEx::get_Color(void) +{ + return logbrush.lbColor; +} + +CBrushEx::operator HBRUSH() +{ + return handle; +} +#ifdef __WTLBUILDER__ +typedef long BrushStyle; +typedef long BrushHatch; +void CBrushEx::AddProperty(const char *Name,CProperties & objprop) +{ + BEGIN_CLASS_SUB_PROPERTY(Name,CBrushEx) + DEFINE_SUB_PROPERTY(Style,BrushStyle,CBrushEx,BS_SOLID) + DEFINE_SUB_PROPERTY(Hatch,BrushHatch,CBrushEx,0) + DEFINE_SUB_PROPERTY(Color,CColorref,CBrushEx,RGB(0xFF,0xFF,0xFF)) + END_CLASS_SUB_PROPERTY +} +#endif +//////////////////////////////////////////////////////////////////////////////////////////////// +#ifdef __WTLBUILDER__ +typedef long CharSet; +#endif +CFontEx::CFontEx():handle(NULL) +{ + lf.lfHeight=-12; + lf.lfWidth=0; + lf.lfEscapement=0; + lf.lfOrientation=0; + lf.lfWeight=FW_NORMAL; + lf.lfItalic=0; + lf.lfUnderline=0; + lf.lfStrikeOut=0; + lf.lfCharSet=DEFAULT_CHARSET; + lf.lfOutPrecision=OUT_DEFAULT_PRECIS; + lf.lfClipPrecision=CLIP_DEFAULT_PRECIS; + lf.lfQuality=PROOF_QUALITY; + lf.lfPitchAndFamily=VARIABLE_PITCH | FF_ROMAN; + strcpy(lf.lfFaceName, "MS Sans Serif"); + + handle=CreateFontIndirect(&lf); + fontColor=0; +} + +CFontEx::CFontEx(const CString & facename) +{ + lf.lfHeight=-12; + lf.lfWidth=0; + lf.lfEscapement=0; + lf.lfOrientation=0; + lf.lfWeight=FW_NORMAL; + lf.lfItalic=0; + lf.lfUnderline=0; + lf.lfStrikeOut=0; + lf.lfCharSet=DEFAULT_CHARSET; + lf.lfOutPrecision=OUT_DEFAULT_PRECIS; + lf.lfClipPrecision=CLIP_DEFAULT_PRECIS; + lf.lfQuality=PROOF_QUALITY; + lf.lfPitchAndFamily=VARIABLE_PITCH | FF_ROMAN; + strcpy(lf.lfFaceName, (LPCSTR)facename); + + handle=CreateFontIndirect(&lf); + + fontColor=0; +} + +CFontEx::CFontEx(LOGFONT& logfont) +{ + lf=logfont; + handle=CreateFontIndirect(&lf); + fontColor=0; +} + +CFontEx::CFontEx(CFont *font) +{ + font->GetLogFont(&lf); + handle=CreateFontIndirect(&lf); + fontColor=0; +} + +CFontEx::CFontEx(CFontEx & font) +{ + font.get_LogFont(lf); + handle=CreateFontIndirect(&lf); + fontColor=0; +} + +CFontEx::~CFontEx() +{ + if(handle) + DeleteObject(handle); +} +#ifdef __WTLBUILDER__ +typedef CString FontFaceName; + +void CFontEx::AddProperty(const char *Name,CProperties & objprop) +{ + BEGIN_CLASS_SUB_PROPERTY(Name,CFontEx) + DEFINE_SUB_PROPERTY(Height,long,CFontEx,get_Height()) + DEFINE_SUB_PROPERTY(Bold,BOOL,CFontEx,get_Bold()) + DEFINE_SUB_PROPERTY(Italic,BOOL,CFontEx,get_Italic()) + DEFINE_SUB_PROPERTY(Underline,BOOL,CFontEx,get_Underline()) + DEFINE_SUB_PROPERTY(StrikeOut,BOOL,CFontEx,get_StrikeOut()) + DEFINE_SUB_PROPERTY(CharSet,CharSet,CFontEx,get_CharSet()) + DEFINE_SUB_PROPERTY(FaceName,FontFaceName,CFontEx,get_FaceName()) + END_CLASS_SUB_PROPERTY + //DEFINE_SUB_PROPERTY(Color,COLORREF,CFontEx,GetColor()) +} +#endif +void CFontEx::set_Height(long height) +{ + DeleteObject(handle); + lf.lfHeight=height; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_Width(long width) +{ + DeleteObject(handle); + lf.lfWidth=width; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_Escapement(long esc) +{ + DeleteObject(handle); + lf.lfEscapement=esc; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_Orientation(long or) +{ + DeleteObject(handle); + lf.lfOrientation=or; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_Weight(long weight) +{ + DeleteObject(handle); + lf.lfWeight=weight; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_CharSet(long charset) +{ + DeleteObject(handle); + lf.lfCharSet=(BYTE)charset; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_OutPrecision(long op) +{ + DeleteObject(handle); + lf.lfOutPrecision=(BYTE)op; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_ClipPrecision(long cp) +{ + DeleteObject(handle); + lf.lfClipPrecision=(BYTE)cp; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_Quality(long qual) +{ + DeleteObject(handle); + lf.lfQuality=(BYTE)qual; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_PitchAndFamily(long paf) +{ + DeleteObject(handle); + lf.lfPitchAndFamily=(BYTE)paf; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_FaceName(CString facename) +{ + DeleteObject(handle); + strcpy(lf.lfFaceName,(LPCSTR)facename); + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_Bold(BOOL B) +{ + if(B) + set_Weight(FW_BOLD); + else + set_Weight(FW_NORMAL); + change(this); +} + +void CFontEx::set_Italic(BOOL i) +{ + DeleteObject(handle); + lf.lfItalic=i; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_Underline(BOOL u) +{ + DeleteObject(handle); + lf.lfUnderline=u; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_StrikeOut(BOOL s) +{ + DeleteObject(handle); + lf.lfStrikeOut=s; + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::set_LogFont(LOGFONT& logfont) +{ + //lf=logfont; + memcpy(&lf,&logfont,sizeof(LOGFONT)); + DeleteObject(handle); + handle=CreateFontIndirect(&lf); + change(this); +} + +void CFontEx::get_LogFont(LOGFONT& logfont) +{ + memcpy(&logfont,&lf,sizeof(LOGFONT)); +} + +long CFontEx::get_Height() +{ + return lf.lfHeight; +} + +long CFontEx::get_Width() +{ + return lf.lfWidth; +} + +long CFontEx::get_Escapement() +{ + return lf.lfEscapement; +} + +long CFontEx::get_Orientation() +{ + return lf.lfEscapement; +} + +long CFontEx::get_Weight() +{ + return lf.lfWeight; +} + +long CFontEx::get_CharSet() +{ + return lf.lfCharSet; +} + +long CFontEx::get_OutPrecision() +{ + return lf.lfOutPrecision; +} + +long CFontEx::get_ClipPrecision() +{ + return lf.lfClipPrecision; +} + +long CFontEx::get_Quality() +{ + return lf.lfQuality; +} + +long CFontEx::get_PitchAndFamily() +{ + return lf.lfPitchAndFamily; +} + +CString CFontEx::get_FaceName() +{ + return lf.lfFaceName; +} + +BOOL CFontEx::get_Bold() +{ + return lf.lfWeight == FW_BOLD ? TRUE : FALSE; +} + +BOOL CFontEx::get_Italic() +{ + return (BOOL)lf.lfItalic; +} + +BOOL CFontEx::get_Underline() +{ + return (BOOL)lf.lfUnderline; +} + +BOOL CFontEx::get_StrikeOut() +{ + return (BOOL)lf.lfStrikeOut; +} + +void CFontEx::set_Color(CColorref color) +{ + fontColor=color; + change(this); +} + +CColorref CFontEx::get_Color(void) +{ + return fontColor; +} + +CFontEx::operator HFONT() +{ + return handle; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +CSel::CSel(HDC DC, HPEN hPen) +{ + m_hOldGdiObject = NULL; + m_pDC = NULL; + + if(DC) + { + ATLASSERT(hPen); + if(hPen) + { + m_pDC = DC; + m_hOldGdiObject = ::SelectObject(m_pDC,hPen); + } + } +} + +CSel::CSel(HDC DC, HBRUSH hBrush) +{ + m_hOldGdiObject = NULL; + m_pDC = NULL; + + if(DC) + { + ATLASSERT(hBrush); + if(hBrush) + { + m_pDC = DC; + m_hOldGdiObject = ::SelectObject(m_pDC,hBrush); + } + } +} + +CSel::CSel(HDC DC, HFONT hFont) +{ + m_hOldGdiObject = NULL; + m_pDC = NULL; + + if(DC) + { + m_pDC = DC; + ATLASSERT(hFont); + if(hFont) + m_hOldGdiObject = ::SelectObject(m_pDC,hFont); + + } +} + +CSel::CSel(HDC DC, int index) +{ + m_hOldGdiObject = NULL; + m_pDC = NULL; + + if(DC) + { + m_pDC = DC; + m_hOldGdiObject = ::SelectObject(m_pDC,::GetStockObject(index)); + } +} + +CSel::~CSel() +{ + if(m_hOldGdiObject && m_pDC) + ::SelectObject(m_pDC, m_hOldGdiObject); + +} +////////////////////////////////////////////////////////////////////////// +void DrawGradientFill(CDC & DC, CRect & pRect, CColorref crStart, CColorref crEnd,int Orient, int nSegments) +{ + if(Orient==grHoriz) + DrawHorGradientFill(DC,pRect,crStart,crEnd,nSegments); + else + DrawVertGradientFill(DC,pRect,crStart,crEnd,nSegments); +} +////////////////////////////////////////////////////////////////////////// +void DrawHorGradientFill(CDC & pDC, CRect &pRect, CColorref crStart, CColorref crEnd, int nSegments) +{ + COLORREF cr; + int nR = GetRValue(crStart); + int nG = GetGValue(crStart); + int nB = GetBValue(crStart); + + int neB = GetBValue(crEnd); + int neG = GetGValue(crEnd); + int neR = GetRValue(crEnd); + + if(nSegments > pRect.Width()) + nSegments = pRect.Width(); + + int nDiffR = (neR - nR); + int nDiffG = (neG - nG); + int nDiffB = (neB - nB); + + int ndR = 256 * (nDiffR) / (max(nSegments,1)); + int ndG = 256 * (nDiffG) / (max(nSegments,1)); + int ndB = 256 * (nDiffB) / (max(nSegments,1)); + + nR *= 256; + nG *= 256; + nB *= 256; + + neR *= 256; + neG *= 256; + neB *= 256; + + int nCX = pRect.Width() / max(nSegments,1), nLeft = pRect.left, nRight; + pDC.SelectStockPen(NULL_PEN); + + for (int i = 0; i < nSegments; i++, nR += ndR, nG += ndG, nB += ndB) + { + // Use special code for the last segment to avoid any problems + // with integer division. + + if (i == (nSegments - 1)) + nRight = pRect.right; + else + nRight = nLeft + nCX; + + cr = RGB(nR / 256, nG / 256, nB / 256); + + { + CBrush br; + br.CreateSolidBrush(cr); + CRect rc(nLeft, pRect.top, nRight + 1, pRect.bottom); + pDC.FillRect(&rc, br); + } + + // Reset the left side of the drawing rectangle. + + nLeft = nRight; + } +} +////////////////////////////////////////////////////////////////////////// +void DrawVertGradientFill(CDC & pDC, CRect &pRect, CColorref crStart, CColorref crEnd, int nSegments) +{ + COLORREF cr; + int nR = GetRValue(crStart); + int nG = GetGValue(crStart); + int nB = GetBValue(crStart); + + int neB = GetBValue(crEnd); + int neG = GetGValue(crEnd); + int neR = GetRValue(crEnd); + + if(nSegments > pRect.Height()) + nSegments = pRect.Height(); + + int nDiffR = (neR - nR); + int nDiffG = (neG - nG); + int nDiffB = (neB - nB); + + int ndR = 256 * (nDiffR) / (max(nSegments,1)); + int ndG = 256 * (nDiffG) / (max(nSegments,1)); + int ndB = 256 * (nDiffB) / (max(nSegments,1)); + + nR *= 256; + nG *= 256; + nB *= 256; + + neR *= 256; + neG *= 256; + neB *= 256; + + int nCY = pRect.Height() / max(nSegments,1), nTop = pRect.top, nBottom; + pDC.SelectStockPen(NULL_PEN); + + for (int i = 0; i < nSegments; i++, nR += ndR, nG += ndG, nB += ndB) + { + // Use special code for the last segment to avoid any problems + // with integer division. + + if (i == (nSegments - 1)) + nBottom = pRect.bottom; + else + nBottom = nTop + nCY; + + cr = RGB(nR / 256, nG / 256, nB / 256); + + { + CBrush br; + br.CreateSolidBrush(cr); + CRect rc(pRect.left, nTop, pRect.right,nBottom + 1); + pDC.FillRect(&rc, br); + } + + // Reset the left side of the drawing rectangle. + + nTop = nBottom; + } +} +////////////////////////////////////////////////////////////////////////// +void DrawGradientText(CDC &DC,int x, int y, CString & text, CColorref crStart, CColorref crEnd, int Orient,int nSegments) +{ + DC.SetBkMode(TRANSPARENT); + DC.BeginPath(); + + DC.TextOut(x,y,(LPCSTR)text,text.GetLength()); + DC.CloseFigure(); + EndPath(DC); + DC.SelectClipPath(RGN_COPY); + SIZE sz; + DC.GetTextExtent((LPCSTR)text,text.GetLength(), &sz); + CRect rc(x,y,x+sz.cx,y+sz.cy); + DrawGradientFill(DC,rc,crStart,crEnd,Orient,nSegments); + SelectClipRgn(DC,NULL); +} +////////////////////////////////////////////////////////////////////////// +void DrawTransparentBitmap (HDC hdc, HBITMAP hBitmap, long xStart, + long yStart, COLORREF cTransparentColor) + { + BITMAP bm; + COLORREF cColor; + HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave; + HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld; + HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave; + POINT ptSize; + + hdcTemp = CreateCompatibleDC(hdc); + SelectObject(hdcTemp, hBitmap); // Select the bitmap + GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); + ptSize.x = bm.bmWidth; // Get width of bitmap + ptSize.y = bm.bmHeight; // Get height of bitmap + DPtoLP(hdcTemp, &ptSize, 1); // Convert from device + // to logical points + + // Create some DCs to hold temporary data. + hdcBack = CreateCompatibleDC(hdc); + hdcObject = CreateCompatibleDC(hdc); + hdcMem = CreateCompatibleDC(hdc); + hdcSave = CreateCompatibleDC(hdc); + // Create a bitmap for each DC. + + // Monochrome DC + bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); + + // Monochrome DC + bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); + bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); + bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); + + // Each DC must select a bitmap object to store pixel data. + bmBackOld = (HBITMAP) SelectObject(hdcBack, bmAndBack); + bmObjectOld = (HBITMAP) SelectObject(hdcObject, bmAndObject); + bmMemOld = (HBITMAP) SelectObject(hdcMem, bmAndMem); + bmSaveOld = (HBITMAP) SelectObject(hdcSave, bmSave); + + // Set proper mapping mode. + SetMapMode(hdcTemp, GetMapMode(hdc)); + + // Save the bitmap sent here, because it will be overwritten. + BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); + + // Set the background color of the source DC to the color. + // contained in the parts of the bitmap that should be transparent + cColor = SetBkColor(hdcTemp, cTransparentColor); + + // Create the object mask for the bitmap by performing a BitBlt + // from the source bitmap to a monochrome bitmap. + BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, + SRCCOPY); + + // Set the background color of the source DC back to the original + // color. + SetBkColor(hdcTemp, cColor); + + // Create the inverse of the object mask. + BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, + NOTSRCCOPY); + + // Copy the background of the main DC to the destination. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, + SRCCOPY); + + // Mask out the places where the bitmap will be placed. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND); + + // Mask out the transparent colored pixels on the bitmap. + BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND); + + // XOR the bitmap with the background on the destination DC. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT); + + // Copy the destination to the screen. + BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, + SRCCOPY); + + // Place the original bitmap back into the bitmap sent here. + BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY); + + // Delete the memory bitmaps. + DeleteObject(SelectObject(hdcBack, bmBackOld)); + DeleteObject(SelectObject(hdcObject, bmObjectOld)); + DeleteObject(SelectObject(hdcMem, bmMemOld)); + DeleteObject(SelectObject(hdcSave, bmSaveOld)); + + // Delete the memory DCs. + DeleteDC(hdcMem); + DeleteDC(hdcBack); + DeleteDC(hdcObject); + DeleteDC(hdcSave); + DeleteDC(hdcTemp); + } + +////////////////////////////////////////////////////////////////////////// +#ifdef __WTLBUILDER__ +#include +BEGIN_LIST_PROPERTY(PenStyle) + LIST_ITEM(PS_SOLID,PS_SOLID) + LIST_ITEM(PS_DASH,PS_DASH) + LIST_ITEM(PS_DOT,PS_DOT) + LIST_ITEM(PS_DASHDOT,PS_DASHDOT) + LIST_ITEM(PS_DASHDOTDOT,PS_DASHDOTDOT) + LIST_ITEM(PS_INSIDEFRAME,PS_INSIDEFRAME) +END_LIST_ITEM(PenStyle) + +BEGIN_LIST_PROPERTY(BrushStyle) + LIST_ITEM(BS_SOLID,BS_SOLID) + LIST_ITEM(BS_HATCHED,BS_HATCHED) + LIST_ITEM(BS_NULL,BS_NULL) +END_LIST_ITEM(BrushStyle) + +BEGIN_LIST_PROPERTY(BrushHatch) + LIST_ITEM(HS_BDIAGONAL,HS_BDIAGONAL) + LIST_ITEM(HS_CROSS,HS_CROSS) + LIST_ITEM(HS_DIAGCROSS,HS_DIAGCROSS) + LIST_ITEM(HS_FDIAGONAL,HS_FDIAGONAL) + LIST_ITEM(HS_HORIZONTAL,HS_HORIZONTAL) + LIST_ITEM(HS_VERTICAL,HS_VERTICAL) +END_LIST_ITEM(BrushHatch) + +BEGIN_LIST_PROPERTY(Bold) + LIST_ITEM_DECORATE(FALSE,FW_NORMAL,false) + LIST_ITEM_DECORATE(TRUE,FW_BOLD,true) +END_LIST_ITEM(Bold) + +BEGIN_LIST_PROPERTY(CharSet) + LIST_ITEM_DECORATE(ANSI_CHARSET,ANSI_CHARSET,Ansi) + LIST_ITEM_DECORATE(DEFAULT_CHARSET,DEFAULT_CHARSET,Default) + LIST_ITEM_DECORATE(SYMBOL_CHARSET,SYMBOL_CHARSET,,Symbol) + LIST_ITEM_DECORATE(SHIFTJIS_CHARSET,SHIFTJIS_CHARSET,ShiftJis) + LIST_ITEM_DECORATE(HANGEUL_CHARSET,HANGEUL_CHARSET,Hangeul) + LIST_ITEM_DECORATE(HANGUL_CHARSET,HANGUL_CHARSET,Hangul) + LIST_ITEM_DECORATE(GB2312_CHARSET,GB2312_CHARSET,GB2312) + LIST_ITEM_DECORATE(CHINESEBIG5_CHARSET,CHINESEBIG5_CHARSET,ChineseBig5) + LIST_ITEM_DECORATE(OEM_CHARSET,OEM_CHARSET,OEM) + LIST_ITEM_DECORATE(JOHAB_CHARSET,JOHAB_CHARSET,Johab) + LIST_ITEM_DECORATE(HEBREW_CHARSET,HEBREW_CHARSET,Hebrew) + LIST_ITEM_DECORATE(ARABIC_CHARSET,ARABIC_CHARSET,Arabic) + LIST_ITEM_DECORATE(GREEK_CHARSET,GREEK_CHARSET,Greek) + LIST_ITEM_DECORATE(TURKISH_CHARSET,TURKISH_CHARSET,Turkish) + LIST_ITEM_DECORATE(VIETNAMESE_CHARSET,VIETNAMESE_CHARSET,Vietnamese) + LIST_ITEM_DECORATE(THAI_CHARSET,THAI_CHARSET,Thai) + LIST_ITEM_DECORATE(EASTEUROPE_CHARSET,EASTEUROPE_CHARSET,EastEurope) + LIST_ITEM_DECORATE(RUSSIAN_CHARSET,RUSSIAN_CHARSET,Russian) +END_LIST_ITEM(CharSet) + +BEGIN_LIST_PROPERTY(OutPrecision) + LIST_ITEM(OUT_CHARACTER_PRECIS,OUT_CHARACTER_PRECIS) + LIST_ITEM(OUT_DEFAULT_PRECIS,OUT_DEFAULT_PRECIS) + LIST_ITEM(OUT_DEVICE_PRECIS,OUT_DEVICE_PRECIS) + LIST_ITEM(OUT_OUTLINE_PRECIS,OUT_OUTLINE_PRECIS) + LIST_ITEM(OUT_RASTER_PRECIS,OUT_RASTER_PRECIS) + LIST_ITEM(OUT_STRING_PRECIS,OUT_STRING_PRECIS) + LIST_ITEM(OUT_STROKE_PRECIS,OUT_STROKE_PRECIS) + LIST_ITEM(OUT_TT_ONLY_PRECIS,OUT_TT_ONLY_PRECIS) + LIST_ITEM(OUT_TT_PRECIS,OUT_TT_PRECIS) +END_LIST_ITEM(OutPrecision) + +BEGIN_LIST_PROPERTY(ClipPrecision) + LIST_ITEM(CLIP_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS) + LIST_ITEM(CLIP_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS) + LIST_ITEM(CLIP_STROKE_PRECIS,CLIP_STROKE_PRECIS) + LIST_ITEM(CLIP_EMBEDDED,CLIP_EMBEDDED) + LIST_ITEM(CLIP_LH_ANGLES,CLIP_LH_ANGLES) +END_LIST_ITEM(ClipPrecision) + +BEGIN_LIST_PROPERTY(Quality) + LIST_ITEM(DEFAULT_QUALITY,DEFAULT_QUALITY) + LIST_ITEM(DRAFT_QUALITY,DRAFT_QUALITY) + LIST_ITEM(PROOF_QUALITY,PROOF_QUALITY) +END_LIST_ITEM(Quality) + +BEGIN_LIST_PROPERTY(VertTextRectAlign) +LIST_ITEM(DT_TOP,DT_TOP) +LIST_ITEM(DT_VCENTER,DT_VCENTER) +LIST_ITEM(DT_BOTTOM,DT_BOTTOM) +END_LIST_ITEM(VertTextRectAlign) + +BEGIN_LIST_PROPERTY(HorizTextRectAlign) +LIST_ITEM(DT_LEFT,DT_LEFT) +LIST_ITEM(DT_CENTER,DT_CENTER) +LIST_ITEM(DT_RIGHT,DT_RIGHT) +END_LIST_ITEM(HorizTextRectAlign) + +typedef CString ImageBmpIcoFileNameType; +typedef CString ImageIcoFileNameType; +typedef CString ImageBmpFileNameType; + +CImage::CImage(int t):type(t),bitmap(NULL),icon(NULL),cx(0),cy(0) +{ +} + +CImage::~CImage() +{ + DeleteObject(); +} + +void CImage::set_FileName(CString val) +{ + fileName=val; + Load(); +} + +CString CImage::get_FileName() +{ + return fileName; +} + +void CImage::DeleteObject() +{ + if(bitmap) + ::DeleteObject(bitmap); + + if(icon) + ::DeleteObject(icon); + bitmap=NULL; + icon=NULL; +} + +BOOL CImage::Load() +{ + if(fileName.IsEmpty()==FALSE) + { + DeleteObject(); + if(CFileName::GetExt((LPCSTR)fileName).CompareNoCase("bmp")==0) + bitmap=(HBITMAP)LoadImage(NULL,fileName,IMAGE_BITMAP,cx,cy,LR_LOADFROMFILE); + else + if(CFileName::GetExt((LPCSTR)fileName).CompareNoCase("ico")==0) + icon=(HICON)LoadImage(NULL,fileName,IMAGE_ICON,cx,cy,LR_LOADFROMFILE); + } + change(this); + ::UpdateProperty(propName+".ImageType"); + return bitmap!=NULL || icon!=NULL; +} + +void CImage::set_Width(long val) +{ + if(cx!=val) + { + cx=val; + Load(); + } +} + +long CImage::get_Width() +{ + return cx; +} + +void CImage::set_Height(long val) +{ + if(cy!=val) + { + cy=val; + Load(); + } +} + +long CImage::get_Height() +{ + return cy; +} + +void CImage::set_ID(CString val) +{ + id=val; +} + +CString CImage::get_ID(void) +{ + return id; +} + +void CImage::set_ImageType(CString) +{ +} + +CString CImage::get_ImageType(void) +{ + if(bitmap) + return "Bitmap"; + else + if(icon) + return "Icon"; + return "None"; +} + +void CImage::AddProperty(const char * Name,CProperties & objprop) +{ + propName=Name; + BEGIN_CLASS_SUB_PROPERTY(Name,CImage) + if((type & BITMAP_TYPE) && (type & ICON_TYPE)) + DEFINE_SUB_PROPERTY(FileName,ImageBmpIcoFileNameType,CImage,fileName) + else + if(type & BITMAP_TYPE) + DEFINE_SUB_PROPERTY(FileName,ImageBmpFileNameType,CImage,fileName) + else + if(type & ICON_TYPE) + DEFINE_SUB_PROPERTY(FileName,ImageIcoFileNameType,CImage,fileName) + DEFINE_SUB_PROPERTY(ID,CString,CImage,"") + DEFINE_SUB_PROPERTY(ImageType,CString,CImage,"None") + DEFINE_SUB_PROPERTY(Width,long,CImage,0) + DEFINE_SUB_PROPERTY(Height,long,CImage,0) + PUBLIC_PROPERTY(ImageType,FALSE) + END_CLASS_SUB_PROPERTY +} + + +void RegisterGDIProp(void) +{ + static IsInited=FALSE; + if(IsInited==TRUE) + return; + + REGISTER_LIST_PROPERTY(Bold) + REGISTER_LIST_PROPERTY(CharSet) + REGISTER_LIST_PROPERTY(OutPrecision) + REGISTER_LIST_PROPERTY(ClipPrecision) + REGISTER_LIST_PROPERTY(Quality) + REGISTER_LIST_PROPERTY(VertTextRectAlign) + REGISTER_LIST_PROPERTY(HorizTextRectAlign) + + // REGISTER_LIST_PROPERTY(BrushStyle) + // REGISTER_LIST_PROPERTY(BrushHatch) + + IsInited=TRUE; +} + +#endif \ No newline at end of file diff --git a/windows/wtlbuilder/GDIUtil.h b/windows/wtlbuilder/GDIUtil.h new file mode 100644 index 000000000..a8227a790 --- /dev/null +++ b/windows/wtlbuilder/GDIUtil.h @@ -0,0 +1,470 @@ +#ifndef __GDIUTIL_H +#define __GDIUTIL_H +using namespace WTL; + +#include "CallBack.h" +////////////////////////////////////////////////////////////////////////// +#ifdef __WTLBUILDER__ +class PropertyBase; +class CProperties; +#define SYSCOLOR_SIGN 0x80000000 +class CColorref +{ +public: + CColorref():color(RGB(0,0,0)){} + CColorref(COLORREF val):color(val) + { + + } + CColorref(int val):color(val|SYSCOLOR_SIGN){} + CColorref(const CColorref &val):color(val.color){} + CColorref & operator=(COLORREF val) + { + color=val; + return *this; + } + + CColorref & operator=(int val) + { + color=val|SYSCOLOR_SIGN; + return *this; + } + + operator COLORREF() + { + return GetColor(); + } + + int operator ==(const CColorref &val) + { + return color==val.color; + } + + COLORREF GetColor() + { + if(color < 0 && color!=CLR_DEFAULT && color!=CLR_NONE) + return ::GetSysColor(color&~SYSCOLOR_SIGN); + return (COLORREF)color; + } + + BYTE GetRed() + { + return (BYTE)GetColor(); + } + + BYTE GetGreen() + { + return (BYTE)(((WORD)(GetColor())) >> 8); + } + + BYTE GetBlue() + { + return ((BYTE)((GetColor())>>16)); + } + +protected: + long color; +}; + +#define BITMAP_TYPE 0x01 +#define ICON_TYPE 0x02 + +class CImage +{ + HBITMAP bitmap; + HICON icon; + CString fileName; + CString id; + int type; + int cx,cy; + CString propName; + + void DeleteObject(); +public: + CImage(int t=BITMAP_TYPE|ICON_TYPE); + ~CImage(); + void set_FileName(CString); + CString get_FileName(); + BOOL Load(); + void set_ID(CString); + CString get_ID(void); + + void set_ImageType(CString); + CString get_ImageType(void); + + void set_Width(long); + long get_Width(); + + void set_Height(long); + long get_Height(); + + void AddProperty(const char *,CProperties &); + DECLARE_CALLBACK(Change,change) + operator HBITMAP(void) + { + return bitmap; + } + + operator HICON() + { + return icon; + } +protected: +}; + +void RegisterGDIProp(void); + +#else +typedef COLORREF CColorref; +#endif +////////////////////////////////////////////////////////////////////////// +inline CPoint LParamToPoint(LPARAM lParam) +{ + return CPoint (GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); +} + +class CPenEx +{ +public: + CPenEx(void); + CPenEx(int style,int width,CColorref color); + ~CPenEx(); + + void set_Style(int); + int get_Style(void); + __declspec(property(get=get_Style, put=set_Style)) int Style; + + void set_Width(int); + int get_Width(void); + __declspec(property(get=get_Width, put=set_Width)) int Width; + + void set_Color(CColorref); + CColorref get_Color(void); + __declspec(property(get=get_Color, put=set_Color)) CColorref Color; +#ifdef __WTLBUILDER__ + void AddProperty(const char *,CProperties &); +#endif + operator HPEN(); + DECLARE_CALLBACK(Change,change) +protected: + LOGPEN logpen; + HPEN handle; +}; + +class CBrushEx +{ +public: + CBrushEx(void); + CBrushEx(CColorref); + CBrushEx(int style,int hatch,CColorref color); + ~CBrushEx(void); + + void set_Style(long); + long get_Style(void); + __declspec(property(get=get_Style, put=set_Style)) long Style; + + void set_Hatch(long); + long get_Hatch(void); + __declspec(property(get=get_Hatch, put=set_Hatch)) long Hatch; + + void set_Color(CColorref); + CColorref get_Color(void); + __declspec(property(get=get_Color, put=set_Color)) CColorref Color; +#ifdef __WTLBUILDER__ + void AddProperty(const char *,CProperties &); +#endif + operator HBRUSH(); + DECLARE_CALLBACK(Change,change) +protected: + LOGBRUSH logbrush; + HBRUSH handle; +}; + +class CFontEx +{ +public: + CFontEx();//Default Constructor + CFontEx(const CString & facename); + CFontEx(LOGFONT& logfont);//LogFont constructor + CFontEx(CFont * font); + CFontEx(CFontEx & font); + virtual ~CFontEx(); + + void set_Height(long height); + long get_Height(void); + __declspec(property(get=get_Height, put=set_Height)) long Height; + + void set_Width(long width); + long get_Width(void); + __declspec(property(get=get_Width, put=get_Width)) long Width; + + void set_Escapement(long esc); + long get_Escapement(void); + __declspec(property(get=get_Escapement, put=set_Escapement)) long Escapement; + + void set_Orientation(long or); + long get_Orientation(void); + __declspec(property(get=get_Orientation, put=set_Orientation)) long Orientation; + + void set_Weight(long weight); + long get_Weight(void); + __declspec(property(get=get_Weight, put=set_Weight)) long Weight; + + void set_CharSet(long charset); + long get_CharSet(); + __declspec(property(get=get_CharSet, put=set_CharSet)) long Charset; + + void set_OutPrecision(long op); + long get_OutPrecision(void); + __declspec(property(get=get_OutPrecision, put=set_OutPrecision)) long OutPrecision; + + void set_ClipPrecision(long cp); + long get_ClipPrecision(void); + __declspec(property(get=get_ClipPrecision, put=set_ClipPrecision)) long ClipPrecision; + + void set_Quality(long qual); + long get_Quality(void); + __declspec(property(get=get_Quality, put=set_Quality)) long Quality; + + void set_PitchAndFamily(long paf); + long get_PitchAndFamily(void); + __declspec(property(get=get_PitchAndFamily, put=set_PitchAndFamily)) long PitchAndFamily; + + void set_FaceName(CString); + CString get_FaceName(void); + __declspec(property(get=get_FaceName, put=set_FaceName)) CString FaceName; + + void set_Bold(BOOL B); + BOOL get_Bold(void); + __declspec(property(get=get_Bold, put=set_Bold)) BOOL Bold; + + void set_Italic(BOOL i); + BOOL get_Italic(void); + __declspec(property(get=get_Italic, put=set_Italic)) BOOL Italic; + + void set_Underline(BOOL u); + BOOL get_Underline(void); + __declspec(property(get=get_Underline, put=set_Underline)) BOOL Underline; + + void set_StrikeOut(BOOL s); + BOOL get_StrikeOut(void); + __declspec(property(get=get_StrikeOut, put=set_StrikeOut)) BOOL StrikeOut; + + void set_LogFont(LOGFONT& logfont); + void get_LogFont(LOGFONT& logfont); + + void set_Color(CColorref color); + CColorref get_Color(void); + __declspec(property(get=get_Color, put=set_Color)) CColorref Color; + +#ifdef __WTLBUILDER__ + void AddProperty(const char *,CProperties &); +#endif + operator HFONT(); + + DECLARE_CALLBACK(Change,change) +protected: + LOGFONT lf; + CColorref fontColor; + HFONT handle; +}; +//////////////////////////////////////////////////////////////////////////////////////////////// +class CSel +{ +public: + CSel(HDC DC, HPEN); + CSel(HDC DC, HBRUSH); + CSel(HDC DC, HFONT); + CSel(HDC DC, int); +protected: + HDC m_pDC; + HANDLE m_hOldGdiObject; +public: + virtual ~CSel(); +}; + +template +void Unused(T rT) +{ + static_cast(rT); +}; + +class CGDI +{ +protected: + HDC m_pDC; + + CGDI(HDC DC) : + m_pDC(DC) + { + } + + virtual ~CGDI() + { + m_pDC = NULL; + } +}; + +class CTextColor : public CGDI +{ + CColorref m_LastColor; + +public: + CTextColor(HDC DC, CColorref theColor) : CGDI(DC), + m_LastColor(RGB(0,0,0)) + { + m_LastColor = ::SetTextColor(m_pDC,theColor); + } + + virtual ~CTextColor() + { + Unused(SetTextColor(m_pDC,m_LastColor)); + } + +}; + +class CBackColor : public CGDI +{ + CColorref m_LastColor; + +public: + CBackColor(HDC DC, CColorref theColor) : CGDI(DC), + m_LastColor(RGB(0,0,0)) + { + m_LastColor = ::SetBkColor(m_pDC,theColor); + } + + virtual ~CBackColor() + { + Unused(::SetBkColor(m_pDC,m_LastColor)); + } +}; + +class CBKMode : public CGDI +{ + int m_LastMode; +public: + CBKMode(HDC DC, int theMode) : CGDI(DC), + m_LastMode(0) + { + m_LastMode = ::SetBkMode(m_pDC,theMode); + } + + virtual ~CBKMode() + { + Unused(::SetBkMode(m_pDC,m_LastMode)); + } +}; + +class CTextAlign : public CGDI +{ +UINT m_Last; + +public: + CTextAlign(HDC DC, UINT nTextAlign) : CGDI(DC), + m_Last(0) + { + m_Last = ::SetTextAlign(m_pDC,nTextAlign); + } + + virtual ~CTextAlign() + { + Unused(::SetTextAlign(m_pDC,m_Last)); + } +}; + + +class CROP : public CGDI +{ +int m_Last; + +public: + CROP(HDC DC, int nROP) : CGDI(DC), + m_Last(0) + { + m_Last = ::SetROP2(m_pDC,nROP); + } + + virtual ~CROP() + { + Unused(::SetROP2(m_pDC,m_Last)); + } +}; + +class CMapMode : public CGDI +{ +int m_Last; +public: + CMapMode(HDC DC, int nMapMode) : CGDI(DC), + m_Last(0) + { + m_Last = ::SetMapMode(m_pDC,nMapMode); + } + + virtual ~CMapMode() + { + Unused(::SetMapMode(m_pDC,m_Last)); + } +}; +////////////////////////////////////////////////////////////////////////// +enum {grHoriz,grVert}; +void DrawGradientFill(CDC & DC, CRect & pRect, CColorref crStart, CColorref crEnd,int Orient=grHoriz, int nSegments=100); +void DrawHorGradientFill(CDC & DC, CRect & pRect, CColorref crStart, CColorref crEnd, int nSegments=100); +void DrawVertGradientFill(CDC & pDC, CRect &pRect, CColorref crStart, CColorref crEnd, int nSegments=100); +void DrawGradientText(CDC & DC,int x, int y, CString & text, CColorref crStart, CColorref crEnd,int Orient=grHoriz, int nSegments=100); +////////////////////////////////////////////////////////////////////////// +class CPaintDCEx : public CDC +{ +private: + CBitmap m_bitmap; // Offscreen bitmap + CBitmap m_oldBitmap; // bitmap originally found in CMemDC + CDC m_pDC; // Saves CDC passed in constructor + CRect m_rect; // Rectangle of drawing area. + BOOL m_bMemDC; // TRUE if CDC really is a Memory DC. +public: + CPaintDCEx(HDC DC, CRect & ClentRect) : CDC(), m_oldBitmap(NULL), m_pDC(DC), m_rect(ClentRect) + { + // Create a Memory DC + CreateCompatibleDC(DC); + //::GetClipBox(DC,&m_rect); + m_bitmap.CreateCompatibleBitmap(DC, m_rect.Width(), m_rect.Height()); + if(m_bitmap.IsNull()) + return; + m_oldBitmap = SelectBitmap(m_bitmap); + //SetWindowOrg(m_rect.left, m_rect.top); + } + + ~CPaintDCEx() + { + // Copy the offscreen bitmap onto the screen. + m_pDC.BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), + *this, m_rect.left, m_rect.top, SRCCOPY); + // Swap back the original bitmap. + SelectBitmap(m_oldBitmap); + m_bitmap.DeleteObject(); + } + + // Allow usage as a pointer + CPaintDCEx * operator->() {return this;} + // Allow usage as a pointer + operator CPaintDCEx*() {return this;} +}; + +inline void DrawBitmap(CDC & dc,HBITMAP bmp,int x ,int y) +{ + CDC memDC; + BITMAP bstruct; + ::GetObject(bmp,sizeof(BITMAP),&bstruct); + memDC.CreateCompatibleDC(dc); + memDC.SetMapMode(dc.GetMapMode()); + CBitmap pOldBitmap = memDC.SelectBitmap(bmp); + dc.BitBlt(x,y,bstruct.bmWidth,bstruct.bmHeight,memDC, + 0,0,SRCCOPY); + memDC.SelectBitmap(pOldBitmap); +} + +void DrawTransparentBitmap (HDC hdc, HBITMAP hBitmap, long xStart, + long yStart, COLORREF cTransparentColor); + +////////////////////////////////////////////////////////////////////////// +#endif \ No newline at end of file diff --git a/windows/wtlbuilder/Panel.cpp b/windows/wtlbuilder/Panel.cpp new file mode 100644 index 000000000..639b665a8 --- /dev/null +++ b/windows/wtlbuilder/Panel.cpp @@ -0,0 +1,268 @@ +#include "stdafx.h" +#include "Panel.h" + +namespace Panel +{ + ///////////////////////////////////////////////////////////////////////////// + CPanel::CPanel(void):caption(""),textcolor(COLOR_BTNTEXT),bkcolor(COLOR_BTNFACE), + inner(BDR_RAISEDINNER),outer(BDR_RAISEDOUTER),edge(BF_RECT),vertAlign(DT_VCENTER),horizAlign(DT_CENTER), + singleLine(DT_SINGLELINE) + { + font.CreateFont(-12,0,0,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, + PROOF_QUALITY,VARIABLE_PITCH | FF_ROMAN,"MS Sans Serif"); + } + + CPanel::~CPanel() + { + } + // CBevelLine message handlers + + LRESULT CPanel::OnPaint(UINT, WPARAM,LPARAM,BOOL&) + { + CPaintDC dc(m_hWnd); // device context for painting + CRect r; + GetClientRect(&r); + dc.FillSolidRect(&r,bkcolor); + + if(!caption.IsEmpty()) + { + CFont oldFont=dc.SelectFont(font); + COLORREF tc=dc.SetTextColor(textcolor); + int bkm=dc.SetBkMode(TRANSPARENT); + dc.DrawText(caption,caption.GetLength(),r,vertAlign|horizAlign|singleLine); + dc.SetTextColor(tc); + dc.SetBkMode(bkm); + dc.SelectFont(oldFont); + } + + dc.DrawEdge(&r,inner|outer,edge); + return 0; + } + + LRESULT CPanel::OnSetFont(UINT, WPARAM wParam,LPARAM lParam,BOOL&) + { + if(wParam) + { + LOGFONT lf; + if(::GetObject((HFONT)wParam,sizeof(LOGFONT),&lf)!=0) + { + font.DeleteObject(); + font.CreateFontIndirect(&lf); + if(lParam) + InvalidateRect(NULL); + } + } + return 0; + } + + LRESULT CPanel::OnGetFont(UINT, WPARAM,LPARAM,BOOL& Handled) + { + Handled=TRUE; + return (LRESULT)(HFONT)font; + } + + LRESULT CPanel::OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return TRUE; + } + + void CPanel::SetInnerBorder(long val) + { + //if(inner!=val) + { + inner=val; + Invalidate(); + UpdateWindow(); + } + } + + long CPanel::GetInnerBorder(void) + { + return inner; + } + + void CPanel::SetOuterBorder(long val) + { + //if(outer!=val) + { + outer=val; + Invalidate(); + UpdateWindow(); + } + } + + long CPanel::GetOuterBorder(void) + { + return outer; + } + + void CPanel::SetEdgeType(long val) + { + //if(edge!=val) + { + edge=val; + Invalidate(); + UpdateWindow(); + } + } + + long CPanel::GetEdgeType(void) + { + return edge; + } + + void CPanel::SetCaption(CString str) + { + //if(caption!=str) + { + caption=str; + Invalidate(); + } + } + + CString CPanel::GetCaption(void) + { + return caption; + } + + void CPanel::SetTextColor(CColorref c) + { + //if(textcolor!=c) + { + textcolor=c; + Invalidate(); + } + } + + CColorref CPanel::GetTextColor(void) + { + return textcolor; + } + + void CPanel::SetBkColor(CColorref c) + { + //if(bkcolor!=c) + { + bkcolor=c; + Invalidate(); + } + } + + CColorref CPanel::GetBkColor(void) + { + return bkcolor; + } + + void CPanel::SetHorizTextAlign(long val) + { + horizAlign&=~(DT_LEFT|DT_CENTER|DT_RIGHT); + horizAlign|=val; + InvalidateRect(NULL); + } + + long CPanel::GetHorizTextAlign(void) + { + return horizAlign & (DT_LEFT|DT_CENTER|DT_RIGHT); + } + + void CPanel::SetVertTextAlign(long val) + { + vertAlign&=~(DT_TOP|DT_VCENTER|DT_BOTTOM); + vertAlign|=val; + InvalidateRect(NULL); + } + + long CPanel::GetVertTextAlign(void) + { + return vertAlign & (DT_TOP|DT_VCENTER|DT_BOTTOM); + } + + void CPanel::SetSingleLine(BOOL val) + { + if(val==TRUE) + singleLine|=DT_SINGLELINE; + else + singleLine&=~DT_SINGLELINE; + InvalidateRect(NULL); + } + + BOOL CPanel::GetSingleLine(void) + { + return (singleLine & DT_SINGLELINE)!=0; + } + ////////////////////////////////////////////////////////////////////////// + CPanelHost::CPanelHost():current(-1) + { + } + + CPanelHost::~CPanelHost() + { + } + + void CPanelHost::AddPanel(CPanel * panel) + { + CRect rc; + GetClientRect(&rc); + panel->MoveWindow(rc); + + if(panels.Find(panel)==-1) + panels.Add(panel); + if(panels.GetSize()==1) + SetCurrent(0l); + } + + long CPanelHost::GetCurrent() + { + return current; + } + + void CPanelHost::SetCurrent(long c) + { + if(c!=-1 && c < panels.GetSize()) + { + if(current!=-1) + panels[current]->ShowWindow(SW_HIDE); + panels[c]->ShowWindow(SW_SHOW); + } + current=c; + } + + void CPanelHost::SetCurrent(CPanel * panel) + { + int idx; + if((idx=panels.Find(panel))!=-1) + SetCurrent(idx); + } + + LRESULT CPanelHost::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + CRect rc; + GetClientRect(&rc); + for(int i=0; i < panels.GetSize(); i++) + panels[i]->MoveWindow(rc); + return 0; + } + + LRESULT CPanelHost::OnShow(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(current!=-1 && wParam==TRUE) + panels[current]->ShowWindow(SW_HIDE); + return 0; + } + + long CPanelHost::GetCount() + { + return panels.GetSize(); + } + + CPanel*CPanelHost::GetAt(long idx) + { + if(idx = 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "GDIUtil.h" +#include + +namespace Panel +{ + class CPanel : public CWindowImpl + { + protected: + long inner; + long outer; + long edge; + CString caption; + CColorref textcolor; + CColorref bkcolor; + CFont font; + long vertAlign; + long horizAlign; + long singleLine; + public: + DECLARE_WND_CLASS(NULL) + + CPanel(void); + virtual ~CPanel(); + + void SetInnerBorder(long); + long GetInnerBorder(void); + __declspec(property(get=GetInnerBorder, put=SetInnerBorder)) long InnerBorder; + + void SetOuterBorder(long); + long GetOuterBorder(void); + __declspec(property(get=GetOuterBorder, put=SetOuterBorder)) long OuterBorder; + + void SetEdgeType(long); + long GetEdgeType(void); + __declspec(property(get=GetEdgeType, put=SetEdgeType)) long EdgeType; + + void SetCaption(CString); + CString GetCaption(void); + __declspec(property(get=GetCaption, put=SetCaption)) CString Caption; + + void SetTextColor(CColorref); + CColorref GetTextColor(void); + __declspec(property(get=GetTextColor, put=SetTextColor)) CColorref TextColor; + + void SetBkColor(CColorref); + CColorref GetBkColor(void); + __declspec(property(get=GetBkColor, put=SetBkColor)) CColorref BkColor; + + void SetHorizTextAlign(long); + long GetHorizTextAlign(void); + __declspec(property(get=GetHorizTextAlign, put=SetHorizTextAlign)) long HorizTextAlign; + + void SetVertTextAlign(long); + long GetVertTextAlign(void); + __declspec(property(get=GetVertTextAlign, put=SetVertTextAlign)) long VertTextAlign; + + void SetSingleLine(BOOL); + BOOL GetSingleLine(void); + __declspec(property(get=GetSingleLine, put=SetSingleLine)) BOOL SingleLine; + + BEGIN_MSG_MAP(CPanel) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_SETFONT,OnSetFont) + MESSAGE_HANDLER(WM_GETFONT,OnGetFont) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) + FORWARD_NOTIFICATIONS() + END_MSG_MAP() + + LRESULT OnPaint(UINT, WPARAM,LPARAM,BOOL&); + LRESULT OnSetFont(UINT, WPARAM,LPARAM,BOOL&); + LRESULT OnGetFont(UINT, WPARAM,LPARAM,BOOL&); + LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + }; + ////////////////////////////////////////////////////////////////////////// + typedef CSimpleArray CPanels; + + class CPanelHost : public CPanel + { + protected: + CPanels panels; + long current; + public: + DECLARE_WND_CLASS(NULL) + + CPanelHost(void); + virtual ~CPanelHost(); + + void AddPanel(CPanel *); + long GetCurrent(); + void SetCurrent(long); + void SetCurrent(CPanel *); + long GetCount(); + CPanel*GetAt(long); + + BEGIN_MSG_MAP(CPanelHost) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_SHOWWINDOW,OnShow) + FORWARD_NOTIFICATIONS() + CHAIN_MSG_MAP(CPanel) + END_MSG_MAP() + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnShow(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + }; +}; +////////////////////////////////////////////////////////////////////////// +#endif +