📄 win32_buddies.cpp
字号:
/*
This file is part of SWAIN (http://sourceforge.net/projects/swain).
Copyright (C) 2006 Daniel Lindstr鰉 and Daniel Nilsson
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "stdafx.h"
#include "win32_client.h"
#include "win32_buddies.h"
#include "../common/BuddyList.h"
#include "../common/BuddyListUI.h"
#include "../common/PacketConnect.h"
#include <commctrl.h>
#define BUDDY_FILE "buddies.txt"
class Win32BuddyListUI : public BuddyListUI {
private:
HWND hUserList;
HWND hGroupList;
int userCount;
int groupCount;
void initUserList(void);
void initGroupList(void);
public:
Win32BuddyListUI(HWND hUL, HWND hGL);
virtual ~Win32BuddyListUI(void);
virtual void clearUsers(void);
virtual void clearGroups(void);
virtual void addUser(int uid, WCHAR *name, int status);
virtual void changeUser(int uid, WCHAR *name, int status);
virtual void addGroup(int gid, WCHAR *name, int status, bool selected);
virtual void changeGroup(int gid, WCHAR *name, int status, bool selected);
int userListProc(HWND hDlg, LPNMHDR pnmh);
int groupListProc(HWND hDlg, LPNMHDR pnmh);
int getSelectedUser(void);
};
static BuddyList *buddyList;
static Win32BuddyListUI *buddyListUI;
static HWND hBuddyDlg;
static HWND hBuddyMenuBar;
static int selected_uid = -1;
static int focused_uid = -1;
static int focused_gid = -1;
static void setFocusedUser(int uid, bool focus);
static void setFocusedGroup(int gid, bool focus);
Win32BuddyListUI::Win32BuddyListUI(HWND hUL, HWND hGL) {
hUserList = hUL;
hGroupList = hGL;
userCount = 0;
groupCount = 0;
initUserList();
initGroupList();
}
Win32BuddyListUI::~Win32BuddyListUI(void) {
}
void Win32BuddyListUI::clearUsers(void) {
ListView_DeleteAllItems(hUserList);
}
void Win32BuddyListUI::clearGroups(void) {
ListView_DeleteAllItems(hGroupList);
}
void Win32BuddyListUI::addUser(int uid, WCHAR *name, int status) {
LVITEM lvI;
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvI.state = 0;
lvI.stateMask = 0;
lvI.iItem = userCount;
lvI.lParam = uid;
lvI.iSubItem = 0;
lvI.pszText = name;
lvI.cchTextMax = (int)wcslen(name);
lvI.iImage = status;
if (ListView_InsertItem(hUserList, &lvI) == -1) {
printf("InsertItem failed!\n");
return;
}
userCount++;
}
void Win32BuddyListUI::changeUser(int uid, WCHAR *name, int status) {
LVFINDINFO lvfi;
LVITEM lvI;
lvfi.flags = LVFI_PARAM;
lvfi.lParam = uid;
int i = ListView_FindItem(hUserList, -1, &lvfi);
if (i == -1) {
printf("changeUser: Can't find user %d\n", uid);
return;
}
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvI.state = 0;
lvI.stateMask = 0;
lvI.iItem = i;
lvI.lParam = uid;
lvI.iSubItem = 0;
lvI.pszText = name;
lvI.cchTextMax = (int)wcslen(name);
lvI.iImage = status;
if (!ListView_SetItem(hUserList, &lvI)) {
printf("changeUser: Can't set user info!\n");
return;
}
}
void Win32BuddyListUI::addGroup(int gid, WCHAR *name, int status, bool selected) {
LVITEM lvI;
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvI.state = selected ? LVIS_SELECTED : 0;
lvI.stateMask = LVIS_SELECTED;
lvI.iItem = groupCount;
lvI.lParam = gid;
lvI.iSubItem = 0;
lvI.pszText = name;
lvI.cchTextMax = (int)wcslen(name);
lvI.iImage = status;
if (ListView_InsertItem(hGroupList, &lvI) == -1) {
printf("InsertItem failed!\n");
return;
}
groupCount++;
}
int Win32BuddyListUI::getSelectedUser(void){
LVITEM lvI;
int iSelect = (int)SendMessage(hUserList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
if(iSelect == -1)
return(-1);
lvI.mask = LVIF_PARAM;
lvI.iItem = iSelect;
lvI.iSubItem = 0;
ListView_GetItem(hUserList, &lvI);
return((int)lvI.lParam);
}
void Win32BuddyListUI::changeGroup(int gid, WCHAR *name, int status, bool selected) {
LVFINDINFO lvfi;
LVITEM lvI;
lvfi.flags = LVFI_PARAM;
lvfi.lParam = gid;
int i = ListView_FindItem(hGroupList, -1, &lvfi);
if (i == -1) {
printf("changeGroup: Can't find group %d\n", gid);
return;
}
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvI.state = selected ? LVIS_SELECTED : 0;
lvI.stateMask = LVIS_SELECTED;
lvI.iItem = i;
lvI.lParam = gid;
lvI.iSubItem = 0;
lvI.pszText = name;
lvI.cchTextMax = (int)wcslen(name);
lvI.iImage = status;
if (!ListView_SetItem(hGroupList, &lvI)) {
printf("changeGroup: Can't set group info!\n");
return;
}
}
static void setFocusedUser(int uid, bool focus) {
HWND hBtn;
bool fav = buddyList->isFavUser(uid);
focused_uid = focus ? uid : -1;
hBtn = GetDlgItem(hBuddyDlg, IDC_ADD_FAVUSER);
ShowWindow(hBtn, (!fav && focus) ? SW_SHOWNA : SW_HIDE);
hBtn = GetDlgItem(hBuddyDlg, IDC_REMOVE_FAVUSER);
ShowWindow(hBtn, (fav && focus) ? SW_SHOWNA : SW_HIDE);
}
static void setFocusedGroup(int gid, bool focus) {
HWND hBtn;
bool fav = buddyList->isFavGroup(gid);
focused_gid = focus ? gid : -1;
hBtn = GetDlgItem(hBuddyDlg, IDC_ADD_FAVGROUP);
ShowWindow(hBtn, (!fav && focus) ? SW_SHOWNA : SW_HIDE);
hBtn = GetDlgItem(hBuddyDlg, IDC_REMOVE_FAVGROUP);
ShowWindow(hBtn, (fav && focus) ? SW_SHOWNA : SW_HIDE);
}
// Message handler for buddies dialog.
INT_PTR CALLBACK Buddies(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hCheck;
bool checked;
int ret;
switch (message)
{
case WM_INITDIALOG:
{
hBuddyDlg = hDlg;
buddyListUI = new Win32BuddyListUI(GetDlgItem(hDlg, IDC_USERLIST), GetDlgItem(hDlg, IDC_GROUPLIST));
buddyList->setUI(buddyListUI);
buddyList->refresh(true, true, true);
hCheck = GetDlgItem(hDlg, IDC_SHOW_FAVUSER);
PostMessage(hCheck, BM_SETCHECK,
buddyList->getOnlyFavUsers() ? BST_CHECKED : BST_UNCHECKED, 0);
hCheck = GetDlgItem(hDlg, IDC_SHOW_FAVGROUP);
PostMessage(hCheck, BM_SETCHECK,
buddyList->getOnlyFavGroups() ? BST_CHECKED : BST_UNCHECKED, 0);
switch (buddyList->getLowestStatus()) {
case STATUS_ONLINE: hCheck = GetDlgItem(hDlg, IDC_SHOW_ONLINE); break;
case STATUS_AWAY: hCheck = GetDlgItem(hDlg, IDC_SHOW_AWAY); break;
case STATUS_OFFLINE:hCheck = GetDlgItem(hDlg, IDC_SHOW_OFFLINE);break;
}
PostMessage(hCheck, BM_SETCHECK, BST_CHECKED, 0);
}
return (INT_PTR)TRUE;
case WM_NOTIFY:
switch (wParam) {
case IDC_USERLIST:
ret = buddyListUI->userListProc(hDlg, (LPNMHDR) lParam);
SetWindowLong(hDlg, DWL_MSGRESULT, ret);
return TRUE;
case IDC_GROUPLIST:
ret = buddyListUI->groupListProc(hDlg, (LPNMHDR) lParam);
SetWindowLong(hDlg, DWL_MSGRESULT, ret);
return TRUE;
case 0: // Igore control 0 or output may be spammed by the printf below!
break;
default:
printf("WM_NOTIFY: Unknown control %d\n", wParam);
break;
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
selected_uid = buddyListUI->getSelectedUser();
if(selected_uid == -1){
MessageBox(hDlg, (TEXT("Select a user.")), (TEXT("Error")), MB_OK);
break;
}
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
case IDCANCEL:
selected_uid = -1;
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
case IDC_REFRESH:
buddyList->refresh(true, true, true);
break;
case IDC_SHOW_FAVGROUP:
hCheck = GetDlgItem(hDlg, IDC_SHOW_FAVGROUP);
checked = (SendMessage(hCheck, BM_GETCHECK,0,0) == BST_CHECKED);
buddyList->showOnlyFavGroups(checked);
buddyList->refresh(false, true, false);
break;
case IDC_SHOW_FAVUSER:
hCheck = GetDlgItem(hDlg, IDC_SHOW_FAVUSER);
checked = (SendMessage(hCheck, BM_GETCHECK,0,0) == BST_CHECKED);
buddyList->showOnlyFavUsers(checked);
buddyList->refresh(true, false, false);
break;
case IDC_SHOW_ONLINE:
buddyList->setLowestStatus(STATUS_ONLINE);
buddyList->refresh(true, false, true);
break;
case IDC_SHOW_AWAY:
buddyList->setLowestStatus(STATUS_AWAY);
buddyList->refresh(true, false, true);
break;
case IDC_SHOW_OFFLINE:
buddyList->setLowestStatus(STATUS_OFFLINE);
buddyList->refresh(true, false, true);
break;
case IDC_ADD_FAVUSER:
buddyList->addFavUser(focused_uid);
setFocusedUser(focused_uid, true); // Updates button
break;
case IDC_ADD_FAVGROUP:
buddyList->addFavGroup(focused_gid);
setFocusedGroup(focused_gid, true); // Updates button
break;
case IDC_REMOVE_FAVUSER:
buddyList->removeFavUser(focused_uid);
setFocusedUser(focused_uid, true); // Updates button
break;
case IDC_REMOVE_FAVGROUP:
buddyList->removeFavGroup(focused_gid);
setFocusedGroup(focused_gid, true); // Updates button
break;
}
break;
case WM_CLOSE:
EndDialog(hDlg, message);
return TRUE;
case WM_DESTROY:
delete buddyListUI;
return TRUE;
}
return (INT_PTR)FALSE;
}
int Win32BuddyListUI::userListProc(HWND hDlg, LPNMHDR pnmh) {
NMLISTVIEW *pnmlv;
switch (pnmh->code) {
case LVN_ITEMCHANGED:
pnmlv = (NMLISTVIEW *)pnmh;
if ((pnmlv->uChanged & LVIF_STATE) &&
((pnmlv->uOldState & LVIS_SELECTED) || (pnmlv->uNewState & LVIS_SELECTED))) {
setFocusedUser((int)pnmlv->lParam, (pnmlv->uNewState & LVIS_SELECTED) != 0);
}
break;
case NM_DBLCLK:
PostMessage(hDlg, WM_COMMAND, IDOK, 0);
break;
}
return FALSE;
}
int Win32BuddyListUI::groupListProc(HWND hDlg, LPNMHDR pnmh) {
NMLISTVIEW *pnmlv;
unsigned int state, mask;
LVITEM lvI;
switch (pnmh->code) {
case LVN_ITEMCHANGING:
pnmlv = (NMLISTVIEW *)pnmh;
if (pnmlv->uChanged & LVIF_STATE) {
bool selected = buddyList->isSelectedGroup((int)pnmlv->lParam);
if (((pnmlv->uOldState & LVIS_SELECTED) && selected) ||
((pnmlv->uNewState & LVIS_SELECTED) && !selected)) {
mask = pnmlv->uOldState ^ pnmlv->uNewState; // old XOR new = the flags that changed
mask &= ~LVIS_SELECTED; // Mask out selected flag
if (mask) {
// Some other flags also changed so we need to change those
// because we are going to veto this change.
ListView_SetItemState(pnmh->hwndFrom, pnmlv->iItem, pnmlv->uNewState & ~LVIS_SELECTED, mask);
}
return TRUE;
}
}
break;
case LVN_ITEMCHANGED:
pnmlv = (NMLISTVIEW *)pnmh;
if ((pnmlv->uChanged & LVIF_STATE) &&
((pnmlv->uOldState & LVIS_SELECTED) || (pnmlv->uNewState & LVIS_SELECTED))) {
setFocusedGroup((int)pnmlv->lParam, (pnmlv->uNewState & LVIS_SELECTED) != 0);
}
break;
case NM_CLICK:
pnmlv = (NMLISTVIEW *)pnmh;
if (pnmlv->iItem < 0) {
printf("Item is < 0: %d\n", pnmlv->iItem);
break;
}
state = ListView_GetItemState(pnmh->hwndFrom, pnmlv->iItem, LVIS_SELECTED);
lvI.mask = LVIF_PARAM;
lvI.iItem = pnmlv->iItem;
lvI.iSubItem = pnmlv->iSubItem;
if (!ListView_GetItem(pnmh->hwndFrom, &lvI)) {
printf("GetItem failed!");
break;
}
if (lvI.lParam < 0) {
printf("bl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -