LRESULT ChatCtrl::onMatchQueue(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) ou->matchQueue(client->getHubUrl()); return 0; }
void UserManager::checkUser(const OnlineUserPtr& user) { if (BOOLSETTING(CHECK_NEW_USERS)) { if (!ClientManager::getInstance()->isMe(user)) { const Client& client = user->getClient(); if (!client.getExcludeCheck() && client.isOp() && (client.isActive() || user->getIdentity().isTcpActive())) { if (!BOOLSETTING(PROT_FAVS) || !FavoriteManager::getInstance()->isNoFavUserOrUserBanUpload(user->getUser())) // !SMT!-opt { if (!isInProtectedUserList(user->getIdentity().getNick())) { try { QueueManager::getInstance()->addList(HintedUser(user->getUser(), client.getHubUrl()), QueueItem::FLAG_USER_CHECK); } catch (const Exception& e) { LogManager::getInstance()->message(e.getError()); } } } } } } }
LRESULT ChatCtrl::onPrivateMessage(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) PrivateFrame::openWindow(HintedUser(ou->getUser(), client->getHubUrl()), Util::emptyStringT, client); return 0; }
void UserConnection::handlePM(const AdcCommand& c, bool echo) noexcept{ const string& message = c.getParam(0); OnlineUserPtr peer = nullptr; OnlineUserPtr me = nullptr; auto cm = ClientManager::getInstance(); { RLock l(cm->getCS()); peer = cm->findOnlineUser(user->getCID(), getHubUrl()); //try to use the same hub so nicks match to a hub, not the perfect solution for CCPM, nicks keep changing when hubs go offline. if(peer && peer->getHubUrl() != hubUrl) setHubUrl(peer->getHubUrl()); me = cm->findOnlineUser(cm->getMe()->getCID(), getHubUrl()); } if (!me || !peer){ //ChatMessage cant be formatted without the OnlineUser! disconnect(true); return; } if (echo) { std::swap(peer, me); } string tmp; auto msg = make_shared<ChatMessage>(message, peer, me, peer); if (c.getParam("TS", 1, tmp)) { msg->setTime(Util::toInt64(tmp)); } msg->setThirdPerson(c.hasFlag("ME", 1)); fire(UserConnectionListener::PrivateMessage(), this, msg); }
LRESULT ChatCtrl::onUnignore(UINT /*uMsg*/, WPARAM /*wParam*/, HWND /*lParam*/, BOOL& /*bHandled*/){ OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) FavoriteManager::getInstance()->removeIgnoredUser(ou->getUser()->getCID()); return 0; }
void Serializer::appendOnlineUserFlags(const OnlineUserPtr& aUser, StringSet& flags_) noexcept { if (aUser->getIdentity().isAway()) { flags_.insert("away"); } if (aUser->getIdentity().isOp()) { flags_.insert("op"); } if (aUser->getIdentity().isBot() || aUser->getIdentity().isHub()) { flags_.insert("bot"); } if (aUser->isHidden()) { flags_.insert("hidden"); } if (aUser->supportsCCPM()) { flags_.insert("ccpm"); } auto cm = aUser->getIdentity().getConnectMode(); if (!aUser->getUser()->isNMDC() && (cm == Identity::MODE_NOCONNECT_PASSIVE || cm == Identity::MODE_NOCONNECT_IP || cm == Identity::MODE_UNDEFINED)) { flags_.insert("noconnect"); } else if (!aUser->getIdentity().isTcpActive(aUser->getClient())) { flags_.insert("passive"); } }
LRESULT ChatCtrl::onAddToFavorites(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) ou->addFav(); return 0; }
double OnlineUserUtils::getNumericInfo(const OnlineUserPtr& aUser, int aPropertyName) noexcept { switch (aPropertyName) { case PROP_SHARED: return Util::toDouble(aUser->getIdentity().getShareSize()); case PROP_UPLOAD_SPEED: return (double)aUser->getIdentity().getAdcConnectionSpeed(false); case PROP_DOWNLOAD_SPEED: return (double)aUser->getIdentity().getAdcConnectionSpeed(true); case PROP_FILES: return Util::toDouble(aUser->getIdentity().getSharedFiles()); case PROP_UPLOAD_SLOTS: return aUser->getIdentity().getSlots(); default: dcassert(0); return 0; } }
LRESULT ChatCtrl::onCheckList(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { const OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) { try { QueueManager::getInstance()->addList(HintedUser(ou->getUser(), client->getHubUrl()), QueueItem::FLAG_USER_CHECK, client->getHubUrl()); } catch(const Exception& e) { LogManager::getInstance()->message(e.getError()); } } return 0; }
LRESULT ChatCtrl::onCopyUserInfo(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { tstring sCopy; const OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) { sCopy = ou->getText(static_cast<uint8_t>(wID - IDC_COPY)); } if (!sCopy.empty()) WinUtil::setClipboard(sCopy); return 0; }
void HubInfo::onUserUpdated(const OnlineUserPtr& aUser, const PropertyIdSet& aUpdatedProperties) noexcept { if (!aUser->isHidden()) { view.onItemUpdated(aUser, aUpdatedProperties); } maybeSend("hub_user_updated", [&] { return Serializer::serializeItem(aUser, onlineUserPropertyHandler); }); }
void HubInfo::on(ClientListener::UserRemoved, const Client*, const OnlineUserPtr& aUser) noexcept { if (!aUser->isHidden()) { view.onItemRemoved(aUser); } maybeSend("hub_user_disconnected", [&] { return Serializer::serializeItem(aUser, onlineUserPropertyHandler); }); }
void ChatCtrl::runUserCommand(UserCommand& uc) { StringMap ucParams; if(!WinUtil::getUCParams(m_hWnd, uc, ucParams)) return; client->getMyIdentity().getParams(ucParams, "my", true); client->getHubIdentity().getParams(ucParams, "hub", false); const OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou != NULL) { StringMap tmp = ucParams; ou->getIdentity().getParams(tmp, "user", true); client->escapeParams(tmp); client->sendUserCmd(uc, tmp); } }
json OnlineUserUtils::serializeUser(const OnlineUserPtr& aUser, int aPropertyName) noexcept { switch (aPropertyName) { case HubInfo::PROP_IP4: return Serializer::serializeIp(aUser->getIdentity().getIp4()); case HubInfo::PROP_IP6: return Serializer::serializeIp(aUser->getIdentity().getIp6()); case HubInfo::PROP_FLAGS: return Serializer::getOnlineUserFlags(aUser); } return nullptr; }
LRESULT ChatCtrl::onGrantSlot(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { const OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) { uint64_t time = 0; switch(wID) { case IDC_GRANTSLOT: time = 600; break; case IDC_GRANTSLOT_DAY: time = 3600; break; case IDC_GRANTSLOT_HOUR: time = 24*3600; break; case IDC_GRANTSLOT_WEEK: time = 7*24*3600; break; case IDC_UNGRANTSLOT: time = 0; break; } if(time > 0) UploadManager::getInstance()->reserveSlot(HintedUser(ou->getUser(), client->getHubUrl()), time); else UploadManager::getInstance()->unreserveSlot(ou->getUser()); } return 0; }
LRESULT ChatCtrl::onOpenUserLog(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) { StringMap params; params["userNI"] = ou->getIdentity().getNick(); params["hubNI"] = client->getHubName(); params["myNI"] = client->getMyNick(); params["userCID"] = ou->getUser()->getCID().toBase32(); params["hubURL"] = client->getHubUrl(); tstring file = Text::toT(Util::validateFileName(SETTING(LOG_DIRECTORY) + Util::formatParams(SETTING(LOG_FILE_PRIVATE_CHAT), params, false))); if(Util::fileExists(Text::fromT(file))) { ShellExecute(NULL, NULL, file.c_str(), NULL, NULL, SW_SHOWNORMAL); } else { MessageBox(CTSTRING(NO_LOG_FOR_USER),CTSTRING(NO_LOG_FOR_USER), MB_OK ); } } return 0; }
std::string OnlineUserUtils::getStringInfo(const OnlineUserPtr& aUser, int aPropertyName) noexcept { switch (aPropertyName) { case HubInfo::PROP_NICK: return aUser->getIdentity().getNick(); case HubInfo::PROP_DESCRIPTION: return aUser->getIdentity().getDescription(); case HubInfo::PROP_EMAIL: return aUser->getIdentity().getEmail(); case HubInfo::PROP_TAG: return aUser->getIdentity().getTag(); case HubInfo::PROP_HUB_URL: return aUser->getHubUrl(); case HubInfo::PROP_HUB_NAME: return aUser->getClient()->getHubName(); case HubInfo::PROP_IP4: return aUser->getIdentity().getIp4(); case HubInfo::PROP_IP6: return aUser->getIdentity().getIp6(); case HubInfo::PROP_CID: return aUser->getUser()->getCID().toBase32(); default: dcassert(0); return 0; } }
int OnlineUserUtils::compareUsers(const OnlineUserPtr& a, const OnlineUserPtr& b, int aPropertyName) noexcept { switch (aPropertyName) { case HubInfo::PROP_NICK: { bool a_isOp = a->getIdentity().isOp(), b_isOp = b->getIdentity().isOp(); if (a_isOp && !b_isOp) return -1; if (!a_isOp && b_isOp) return 1; if (SETTING(SORT_FAVUSERS_FIRST)) { bool a_isFav = a->getUser()->isFavorite(), b_isFav = b->getUser()->isFavorite(); if (a_isFav && !b_isFav) return -1; if (!a_isFav && b_isFav) return 1; } return Util::DefaultSort(a->getIdentity().getNick(), b->getIdentity().getNick()); } default: dcassert(0); } return 0; }
LRESULT ChatCtrl::onReport(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { const OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) { CHARFORMAT2 cf; memzero(&cf, sizeof(CHARFORMAT2)); cf.cbSize = sizeof(cf); cf.dwMask = CFM_BACKCOLOR | CFM_COLOR | CFM_BOLD; cf.crBackColor = SETTING(BACKGROUND_COLOR); cf.crTextColor = SETTING(ERROR_COLOR); AppendText(Identity(NULL, 0), Text::toT(client->getCurrentNick()), Text::toT("[" + Util::getShortTimeString() + "] "), Text::toT(WinUtil::getReport(ou->getIdentity(), m_hWnd)) + _T('\n'), cf, false); } return 0; }
StringSet Serializer::getOnlineUserFlags(const OnlineUserPtr& aUser) noexcept { auto flags = getUserFlags(aUser->getUser()); appendOnlineUserFlags(aUser, flags); return flags; }
bool OnlineUser::NickSort::operator()(const OnlineUserPtr& left, const OnlineUserPtr& right) const { return compare(left->getIdentity().getNick(), right->getIdentity().getNick()) < 0; }
string OnlineUser::HubName::operator()(const OnlineUserPtr& u) { return u->getClient()->getHubName(); }
void ChatCtrl::AppendText(const Identity& i, const tstring& sMyNick, const tstring& sTime, tstring sMsg, CHARFORMAT2& cf, bool bUseEmo/* = true*/) { SetRedraw(FALSE); SCROLLINFO si = { 0 }; POINT pt = { 0 }; si.cbSize = sizeof(si); si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; GetScrollInfo(SB_VERT, &si); GetScrollPos(&pt); LONG lSelBegin = 0, lSelEnd = 0, lTextLimit = 0, lNewTextLen = 0; LONG lSelBeginSaved, lSelEndSaved; // Unify line endings tstring::size_type j = 0; while((j = sMsg.find(_T("\r"), j)) != tstring::npos) sMsg.erase(j, 1); GetSel(lSelBeginSaved, lSelEndSaved); lSelEnd = lSelBegin = GetTextLengthEx(GTL_NUMCHARS); bool isMyMessage = i.getUser() == ClientManager::getInstance()->getMe(); tstring sLine = sTime + sMsg; // Remove old chat if size exceeds lNewTextLen = sLine.size(); lTextLimit = GetLimitText(); if(lSelEnd + lNewTextLen > lTextLimit) { LONG lRemoveChars = 0; int multiplier = 1; if(lNewTextLen >= lTextLimit) { lRemoveChars = lSelEnd; magnets.clear(); } else { while(lRemoveChars < lNewTextLen) lRemoveChars = LineIndex(LineFromChar(multiplier++ * lTextLimit / 10)); } if(magnets.size()) { tstring buf; buf.resize(lRemoveChars); GetTextRange(0, lRemoveChars, &buf[0]); CHARFORMAT2 cfSel; cfSel.cbSize = sizeof(CHARFORMAT2); for(TStringMap::iterator i = magnets.begin(); i != magnets.end();) { tstring::size_type j = 0; while((j = buf.find(i->first, j)) != tstring::npos) { SetSel(j, j + i->first.size()); GetSelectionCharFormat(cfSel); if(cfSel.dwEffects & CFE_LINK) { magnets.erase(i++); break; } j += i->first.size(); } if(j == tstring::npos) { ++i; } } } // Update selection ranges lSelEnd = lSelBegin -= lRemoveChars; lSelEndSaved -= lRemoveChars; lSelBeginSaved -= lRemoveChars; // ...and the scroll position pt.y -= PosFromChar(lRemoveChars).y; SetSel(0, lRemoveChars); ReplaceSel(_T("")); } // Add to the end SetSel(lSelBegin, lSelEnd); setText(sLine); CHARFORMAT2 enc; enc.bCharSet = RUSSIAN_CHARSET; enc.dwMask = CFM_CHARSET; SetSel(0, sLine.length()); SetSelectionCharFormat(enc); // Format TimeStamp if(!sTime.empty()) { lSelEnd += sTime.size(); SetSel(lSelBegin, lSelEnd - 1); SetSelectionCharFormat(WinUtil::m_TextStyleTimestamp); PARAFORMAT2 pf; memzero(&pf, sizeof(PARAFORMAT2)); pf.dwMask = PFM_STARTINDENT; pf.dxStartIndent = 0; SetParaFormat(pf); } // Authors nick tstring sAuthor = Text::toT(i.getNick()); if(!sAuthor.empty()) { LONG iLen = (sMsg[0] == _T('*')) ? 1 : 0; LONG iAuthorLen = sAuthor.size() + 1; sMsg.erase(0, iAuthorLen + iLen); lSelBegin = lSelEnd; lSelEnd += iAuthorLen + iLen; if(isMyMessage) { SetSel(lSelBegin, lSelBegin + iLen + 1); SetSelectionCharFormat(WinUtil::m_ChatTextMyOwn); SetSel(lSelBegin + iLen + 1, lSelBegin + iLen + iAuthorLen); SetSelectionCharFormat(WinUtil::m_TextStyleMyNick); } else { bool isFavorite = FavoriteManager::getInstance()->isFavoriteUser(i.getUser()); if(BOOLSETTING(BOLD_AUTHOR_MESS) || isFavorite || i.isOp()) { SetSel(lSelBegin, lSelBegin + iLen + 1); SetSelectionCharFormat(cf); SetSel(lSelBegin + iLen + 1, lSelEnd); if(isFavorite){ SetSelectionCharFormat(WinUtil::m_TextStyleFavUsers); } else if(i.isOp()) { SetSelectionCharFormat(WinUtil::m_TextStyleOPs); } else { SetSelectionCharFormat(WinUtil::m_TextStyleBold); } } else { SetSel(lSelBegin, lSelEnd); SetSelectionCharFormat(cf); } } } else { bool thirdPerson = false; switch(sMsg[0]) { case _T('*'): if(sMsg[1] != _T(' ')) break; thirdPerson = true; case _T('<'): tstring::size_type iAuthorLen = sMsg.find(thirdPerson ? _T(' ') : _T('>'), thirdPerson ? 2 : 1); if(iAuthorLen != tstring::npos) { bool isOp = false, isFavorite = false; if(client != NULL) { tstring nick(sMsg.c_str() + 1); nick.erase(iAuthorLen - 1); const OnlineUserPtr ou = client->findUser(Text::fromT(nick)); if(ou != NULL) { isFavorite = FavoriteManager::getInstance()->isFavoriteUser(ou->getUser()); isOp = ou->getIdentity().isOp(); } } lSelBegin = lSelEnd; lSelEnd += iAuthorLen; sMsg.erase(0, iAuthorLen); if(BOOLSETTING(BOLD_AUTHOR_MESS) || isFavorite || isOp) { SetSel(lSelBegin, lSelBegin + 1); SetSelectionCharFormat(cf); SetSel(lSelBegin + 1, lSelEnd); if(isFavorite){ SetSelectionCharFormat(WinUtil::m_TextStyleFavUsers); } else if(isOp) { SetSelectionCharFormat(WinUtil::m_TextStyleOPs); } else { SetSelectionCharFormat(WinUtil::m_TextStyleBold); } } else { SetSel(lSelBegin, lSelEnd); SetSelectionCharFormat(cf); } } } } // Format the message part FormatChatLine(sMyNick, sMsg, cf, isMyMessage, sAuthor, lSelEnd, bUseEmo); SetSel(lSelBeginSaved, lSelEndSaved); if( isMyMessage || ((si.nPage == 0 || (size_t)si.nPos >= (size_t)si.nMax - si.nPage - 5) && (lSelBeginSaved == lSelEndSaved || !selectedUser.empty() || !selectedIP.empty() || !selectedURL.empty()))) { PostMessage(EM_SCROLL, SB_BOTTOM, 0); } else { SetScrollPos(&pt); } // Force window to redraw SetRedraw(TRUE); InvalidateRect(NULL); }
LRESULT ChatCtrl::onContextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) { POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; // location of mouse click if(pt.x == -1 && pt.y == -1) { CRect erc; GetRect(&erc); pt.x = erc.Width() / 2; pt.y = erc.Height() / 2; ClientToScreen(&pt); } POINT ptCl = pt; ScreenToClient(&ptCl); OnRButtonDown(ptCl); bool boHitURL = HitURL(); if (!boHitURL) selectedURL.clear(); OMenu menu; menu.CreatePopupMenu(); if (copyMenu.m_hMenu != NULL) { // delete copy menu if it exists copyMenu.DestroyMenu(); copyMenu.m_hMenu = NULL; } if(selectedUser.empty()) { if(!selectedIP.empty()) { menu.InsertSeparatorFirst(selectedIP); menu.AppendMenu(MF_STRING, IDC_WHOIS_IP, (TSTRING(WHO_IS) + _T(" ") + selectedIP).c_str() ); if (client && client->isOp()) { menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_STRING, IDC_BAN_IP, (_T("!banip ") + selectedIP).c_str()); menu.SetMenuDefaultItem(IDC_BAN_IP); menu.AppendMenu(MF_STRING, IDC_UNBAN_IP, (_T("!unban ") + selectedIP).c_str()); menu.AppendMenu(MF_SEPARATOR); } } else { menu.InsertSeparatorFirst(_T("Text")); } menu.AppendMenu(MF_STRING, ID_EDIT_COPY, CTSTRING(COPY)); menu.AppendMenu(MF_STRING, IDC_COPY_ACTUAL_LINE, CTSTRING(COPY_LINE)); if(!selectedURL.empty()) menu.AppendMenu(MF_STRING, IDC_COPY_URL, CTSTRING(COPY_URL)); } else { bool isMe = (selectedUser == Text::toT(client->getMyNick())); // click on nick copyMenu.CreatePopupMenu(); copyMenu.InsertSeparatorFirst(TSTRING(COPY)); for(int j=0; j < OnlineUser::COLUMN_LAST; j++) { copyMenu.AppendMenu(MF_STRING, IDC_COPY + j, CTSTRING_I(HubFrame::columnNames[j])); } menu.InsertSeparatorFirst(selectedUser); if(!isMe) { menu.AppendMenu(MF_STRING, IDC_GETLIST, CTSTRING(GET_FILE_LIST)); menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_STRING, IDC_PRIVATEMESSAGE, CTSTRING(SEND_PRIVATE_MESSAGE)); menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_STRING, IDC_PUBLIC_MESSAGE, CTSTRING(SEND_PUBLIC_MESSAGE)); menu.AppendMenu(MF_STRING, IDC_SELECT_USER, CTSTRING(SELECT_USER_LIST)); } if(BOOLSETTING(LOG_PRIVATE_CHAT)) { menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_STRING, IDC_OPEN_USER_LOG, CTSTRING(OPEN_USER_LOG)); } menu.AppendMenu(MF_SEPARATOR); if(!isMe) { menu.AppendMenu(MF_STRING, IDC_ADD_TO_FAVORITES, CTSTRING(ADD_TO_FAVORITES)); const OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(!FavoriteManager::getInstance()->isIgnoredUser(ou->getUser()->getCID())) { menu.AppendMenu(MF_STRING, IDC_IGNORE, CTSTRING(IGNORE_USER)); } else { menu.AppendMenu(MF_STRING, IDC_UNIGNORE, CTSTRING(UNIGNORE_USER)); } menu.AppendMenu(MF_SEPARATOR); } menu.AppendMenu(MF_POPUP, (UINT)(HMENU)copyMenu, CTSTRING(COPY)); if(!isMe) { menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_POPUP, (UINT)(HMENU)WinUtil::grantMenu, CTSTRING(GRANT_SLOTS_MENU)); menu.AppendMenu(MF_STRING, IDC_MATCH_QUEUE, CTSTRING(MATCH_QUEUE)); // add user commands prepareMenu(menu, ::UserCommand::CONTEXT_USER, client->getHubUrl()); } // default doubleclick action switch(SETTING(CHAT_DBLCLICK)) { case 0: menu.SetMenuDefaultItem(IDC_SELECT_USER); break; case 1: menu.SetMenuDefaultItem(IDC_PUBLIC_MESSAGE); break; case 2: menu.SetMenuDefaultItem(IDC_PRIVATEMESSAGE); break; case 3: menu.SetMenuDefaultItem(IDC_GETLIST); break; case 4: menu.SetMenuDefaultItem(IDC_MATCH_QUEUE); break; case 6: menu.SetMenuDefaultItem(IDC_ADD_TO_FAVORITES); break; } } menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_STRING, ID_EDIT_SELECT_ALL, CTSTRING(SELECT_ALL)); menu.AppendMenu(MF_STRING, ID_EDIT_CLEAR_ALL, CTSTRING(CLEAR)); //flag to indicate pop up menu. m_bPopupMenu = true; menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, m_hWnd); return 0; }