Exemplo n.º 1
0
// thread tolerant, if updating id dont pass proto, if updating proto dont pass id
void contactDir_Contact_Add(contactDir * cd, HANDLE hContact, char * proto, char * id)
{
    // if a contact is gonna exist anywhere it's going to be in the ->protoCache which has a key of hContact
    // if id is not null then the contact should be indexed via the ->contactCache instead
    if ( id  ==  NULL ) {
        int index = 0;
        contactEntry e;
        e.hContact=hContact;
        e.proto = proto;
        e.id = "";
        EnterCriticalSection(&cd->csLock);
        if ( List_GetIndex(&cd->protoCache, &e, &index) ) {
            contactEntry * p = cd->protoCache.items[index];
            // this hContact is in the cache, protcol changing?
            p->proto = contactDir_Proto_Add(cd, proto); // just replace the old pointer
        } else {
            contactEntry * p = 0;
            // this hContact isn't in the cache, add it
            p = HeapAlloc(hCacheHeap, HEAP_NO_SERIALIZE, sizeof(contactEntry));
            p->proto = contactDir_Proto_Add(cd, proto);
            p->id = 0;
            p->hContact = hContact;
            // add it
            List_Insert(&cd->protoCache, p, index);
        }
        LeaveCriticalSection(&cd->csLock);
    } else {
        // this contact HAS to be in ->protoCache since it was added during startup
        // need to find the contactEntry* that should already exist for it
    } //if
}
Exemplo n.º 2
0
ClcCacheEntry *GetCLCFullCacheEntry(struct ClcData *dat,MCONTACT hContact)
{
	if (hContact == 0)
		return NULL;

	ClcCacheEntry dnce;
	dnce.hContact = hContact;
	ClcCacheEntry *pdnce = (ClcCacheEntry*)List_Find(&dat->lCLCContactsCache,&dnce);
	if (pdnce == NULL) {
		pdnce = (ClcCacheEntry*)mir_calloc(sizeof(ClcCacheEntry));
		pdnce->hContact = hContact;

		int idx;
		List_GetIndex(&dat->lCLCContactsCache,pdnce,&idx);
		List_Insert(&dat->lCLCContactsCache,pdnce,idx);

		ClcCacheEntry *pdnce2 = (ClcCacheEntry*)List_Find(&dat->lCLCContactsCache,&dnce);//for check
		if (pdnce2->hContact != pdnce->hContact)
			return NULL;

		if (pdnce2 != pdnce)
			return NULL;
	}

	return (pdnce);
}
Exemplo n.º 3
0
MIR_CORE_DLL(void*) List_Find(SortedList* p_list, void* p_value)
{
	int idx;
	if (!List_GetIndex(p_list, p_value, &idx))
		return NULL;

	return p_list->items[idx];
}
Exemplo n.º 4
0
MIR_CORE_DLL(int) List_RemovePtr(SortedList* list, void* p)
{
	int idx = -1;
	if (List_GetIndex(list, p, &idx))
		List_Remove(list, idx);

	return idx;
}
Exemplo n.º 5
0
MIR_CORE_DLL(void*) List_Find(SortedList* p_list, void* p_value)
{
	int index;

	if ( !List_GetIndex(p_list, p_value, &index))
		return(NULL);

	return(p_list->items[ index ]);
}
Exemplo n.º 6
0
MIR_CORE_DLL(int) List_InsertPtr(SortedList* list, void* p)
{
	if (p == NULL)
		return -1;

	int idx = list->realCount;
	List_GetIndex(list, p, &idx);
	return List_Insert(list, p, idx);
}
Exemplo n.º 7
0
int Car_Insert(int carnum) {
	int c = List_GetIndex(CarList, carnum);
	if (c < 0 && CarList->length != carnum) {
		return FALSE;
	}
	PTCar car = Car_Create();
	PTListItem pli = List_Insert(CarList, (void *) car, carnum);
	pli->destroy_func = (TItem_Destroy_Func) Car_Destroy;
	return TRUE;
}
Exemplo n.º 8
0
static INT_PTR DbEventTypeGet(WPARAM wParam, LPARAM lParam)
{
	DBEVENTTYPEDESCR tmp;
	int idx;

	tmp.module = (char*)wParam;
	tmp.eventType = lParam;
	if (!List_GetIndex((SortedList*)&eventTypes, &tmp, &idx))
		return 0;

	return (INT_PTR)eventTypes[idx];
}
Exemplo n.º 9
0
int Axle_Insert(int carnum, int i) {
	PTCar car = Car_Get(carnum);
	if (car == NULL) {
		return FALSE;
	}
	int c = List_GetIndex(car->axles, i);
	if (c < 0 && car->axles->length != i) {
		return FALSE;
	}
	PTAxle axle = Axle_Create();
	PTListItem pli = List_Insert(car->axles, (void *) axle, i);
	pli->destroy_func = (TItem_Destroy_Func) Axle_Destroy;
	return TRUE;
}
Exemplo n.º 10
0
// cache the protocol string so that its not allocated per contact but shared
char * contactDir_Proto_Add(contactDir * cd, char * proto)
{
    int index = 0 ;
    char * szCache = 0;
    EnterCriticalSection(&cd->csLock);
    if ( List_GetIndex(&cd->protoNameCache, proto, &index) ) szCache = cd->protoNameCache.items[index];
    else {
        szCache = HeapAlloc(hCacheHeap, HEAP_NO_SERIALIZE, strlen(proto)+1);
        strcpy(szCache, proto);
        List_Insert(&cd->protoNameCache, szCache, index);
    }
    LeaveCriticalSection(&cd->csLock);
    return szCache;
}
Exemplo n.º 11
0
INT_PTR registerToken(WPARAM wParam, LPARAM lParam)
{
	DWORD hash;
	int idx;

	TOKENREGISTEREX *newVr = (TOKENREGISTEREX*)lParam;
	if (newVr == NULL || newVr->szTokenString == NULL || newVr->cbSize <= 0)
		return -1;

	if (newVr->flags & TRF_TCHAR) {
		deRegisterToken(newVr->tszTokenString);
		hash = NameHashFunction(newVr->tszTokenString);
	}
	else {
		WCHAR *wtoken = mir_a2t(newVr->szTokenString);
		deRegisterToken(wtoken);
		hash = NameHashFunction(wtoken);
		mir_free(wtoken);
	}

	TokenRegisterEntry *tre = (TokenRegisterEntry*)mir_alloc(sizeof(TokenRegisterEntry));
	if (tre == NULL)
		return -1;

	memcpy(&tre->tr, newVr, newVr->cbSize);
	tre->nameHash = hash;
	if (!mir_tstrcmp(newVr->tszTokenString, _T("alias")))
		log_debugA("alias");

	if (!(newVr->flags & TRF_PARSEFUNC) && newVr->szService != NULL)
		tre->tr.szService = mir_strdup(newVr->szService);

	if (newVr->flags & TRF_TCHAR)
		tre->tr.tszTokenString = mir_tstrdup(newVr->tszTokenString);
	else
		tre->tr.tszTokenString = mir_a2t(newVr->szTokenString);

	if (newVr->szHelpText != NULL)
		tre->tr.szHelpText = mir_strdup(newVr->szHelpText);

	if ((newVr->flags & TRF_CLEANUP) && !(newVr->flags & TRF_CLEANUPFUNC) && newVr->szCleanupService != NULL)
		tre->tr.szCleanupService = mir_strdup(newVr->szCleanupService);

	mir_cslock lck(csRegister);
	List_GetIndex((SortedList*)&tokens, tre, &idx);
	List_Insert((SortedList*)&tokens, tre, idx);
	return 0;
}
Exemplo n.º 12
0
// thread safe
char * contactDir_Proto_Get(contactDir * cd, HANDLE hContact)
{
    char * szCache = 0;
    int index = 0;
    contactEntry e;
    e.hContact=hContact;
    e.proto="";
    e.id="";
    EnterCriticalSection(&cd->csLock);
    if ( List_GetIndex(&cd->protoCache, &e, &index) ) {
        contactEntry * p = cd->protoCache.items[index];
        szCache = p->proto;
    }
    LeaveCriticalSection(&cd->csLock);
    return szCache;
}
Exemplo n.º 13
0
void InitDisplayNameCache(SortedList *list)
{
	int i, idx;

	memset(list,0,sizeof(SortedList));
	list->sortFunc = (FSortFunc)handleCompare;
	list->increment = CallService(MS_DB_CONTACT_GETCOUNT,0,0)+1;

	i = 0;
	for (HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) {
		ClcCacheEntry *pdnce = (ClcCacheEntry *)mir_calloc(sizeof(ClcCacheEntry));
		pdnce->hContact = hContact;
		InvalidateDisplayNameCacheEntryByPDNE(hContact,pdnce,0);
		List_GetIndex(list,pdnce,&idx);
		List_Insert(list,pdnce,idx);
		i++;
}	}
Exemplo n.º 14
0
int RichUtil_SubClass(HWND hwndEdit)
{
	if (IsWindow(hwndEdit)) {
		int idx;

		TRichUtil *ru = (TRichUtil *)mir_calloc(sizeof(TRichUtil));

		ru->hwnd = hwndEdit;
		ru->hasUglyBorder = 0;
		{
			mir_cslock lck(csRich);
			if (!List_GetIndex(&sListInt, ru, &idx))
				List_Insert(&sListInt, ru, idx);
		}
		mir_subclassWindow(ru->hwnd, RichUtil_Proc);
		RichUtil_ClearUglyBorder(ru);
		return 1;
	}
	return 0;
}
Exemplo n.º 15
0
HINSTANCE GetInstByAddress( void* codePtr )
{
	int idx;
	HINSTANCE result;
	pluginEntry p; p.bpi.hInst = ( HINSTANCE )codePtr;

	if ( pluginListAddr.getCount() == 0 )
		return NULL;

	List_GetIndex(( SortedList* )&pluginListAddr, &p, &idx );
	if ( idx > 0 )
		idx--;

	result = pluginListAddr[idx]->bpi.hInst;

	if (result < hMirandaInst && codePtr > hMirandaInst)
		result = hMirandaInst;
	else if ( idx == 0 && codePtr < ( void* )result )
		result = NULL;

	return result;
}
Exemplo n.º 16
0
static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	TRichUtil *ru = NULL, tru;
	int idx;
	LRESULT ret;

	tru.hwnd = hwnd;
	{
		mir_cslock lck(csRich);
		if (List_GetIndex(&sListInt, &tru, &idx))
			ru = (TRichUtil *)sListInt.items[idx];
	}

	switch (msg) {
	case WM_THEMECHANGED:
	case WM_STYLECHANGED:
		RichUtil_ClearUglyBorder(ru);
		break;

	case WM_NCPAINT:
		ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
		if (ru->hasUglyBorder && IsThemeActive())
		{
			HANDLE hTheme = OpenThemeData(ru->hwnd, L"EDIT");

			if (hTheme) {
				RECT rcBorder;
				RECT rcClient;
				int nState;
				HDC hdc = GetWindowDC(ru->hwnd);

				GetWindowRect(hwnd, &rcBorder);
				rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top;
				rcBorder.left = rcBorder.top = 0;
				CopyRect(&rcClient, &rcBorder);
				rcClient.left += ru->rect.left;
				rcClient.top += ru->rect.top;
				rcClient.right -= ru->rect.right;
				rcClient.bottom -= ru->rect.bottom;
				ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);

				if (IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL))
					DrawThemeParentBackground(hwnd, hdc, &rcBorder);

				if (!IsWindowEnabled(hwnd))
					nState = ETS_DISABLED;
				else if (SendMessage(hwnd, EM_GETOPTIONS, 0, 0) & ECO_READONLY)
					nState = ETS_READONLY;
				else nState = ETS_NORMAL;

				DrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL);
				CloseThemeData(hTheme);
				ReleaseDC(hwnd, hdc);
				return 0;
			}
		}
		return ret;

	case WM_NCCALCSIZE:
		{
			ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
			NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS *)lParam;

			if (ru->hasUglyBorder && IsThemeActive()) {
				HANDLE hTheme = OpenThemeData(hwnd, L"EDIT");
				if (hTheme) {
					RECT rcClient = {0};
					HDC hdc = GetDC(GetParent(hwnd));

					if (GetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK) {
						ru->rect.left = rcClient.left - ncsParam->rgrc[0].left;
						ru->rect.top = rcClient.top - ncsParam->rgrc[0].top;
						ru->rect.right = ncsParam->rgrc[0].right - rcClient.right;
						ru->rect.bottom = ncsParam->rgrc[0].bottom - rcClient.bottom;
						ncsParam->rgrc[0] = rcClient;

						CloseThemeData(hTheme);
						ReleaseDC(GetParent(hwnd), hdc);
						return WVR_REDRAW;
					}
					ReleaseDC(GetParent(hwnd), hdc);
					CloseThemeData(hTheme);
				}
			}
		}
		return ret;

	case WM_ENABLE:
		RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW | RDW_FRAME);
		break;

	case WM_GETDLGCODE:
		return mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam) & ~DLGC_HASSETSEL;

	case WM_NCDESTROY:
		ret = mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
		{
			mir_cslock lck(csRich);
			List_Remove(&sListInt, idx);
		}
		mir_free(ru);
		return ret;
	}
	return mir_callNextSubclass(hwnd, RichUtil_Proc, msg, wParam, lParam);
}
Exemplo n.º 17
0
static INT_PTR CALLBACK ConsoleDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
	switch(message) {
	case WM_INITDIALOG:
	{
		TCHAR title[MAX_PATH];
		TCHAR name[MAX_PATH] = {0};
		TCHAR path[MAX_PATH] = {0};

		hTabs = GetDlgItem(hwndDlg, IDC_TABS);

		//TabCtrl_SetMinTabWidth(hTabs, 100);

		// restore position
		Utils_RestoreWindowPositionEx(hwndDlg,RWPF_HIDDEN,NULL,"Console","Console");

		CallService(MS_DB_GETPROFILENAMET,(WPARAM)SIZEOF(name),(LPARAM)name);

		CallService(MS_DB_GETPROFILEPATHT,(WPARAM)SIZEOF(path),(LPARAM)path);

		mir_sntprintf(title, SIZEOF(title), _T("%s - %s\\%s"), TranslateT("Miranda Console"), path, name);

		SetWindowText(hwndDlg, title);
		SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(LPARAM)hIcons[0]);

		hwndConsole = hwndDlg;
		SendMessage(hwndDlg, HM_ADD, 0, 0);
		PostMessage(hwndDlg, WM_SIZE, 0, 0);
		break;
	}
	case HM_DUMP:
	{
		// lParam = DUMPMSG
		int idx;
		LOGWIN *lw;
		LOGWIN lw2;
		DUMPMSG *dumpMsg = (DUMPMSG*)lParam;

		if (!pActive) {
			mir_free(dumpMsg);
			break;
		}

		if (!gSingleMode)
		{
			lw2.Module = dumpMsg->szModule;
			if (!List_GetIndex(&lModules, &lw2, &idx))
				SendMessage(hwndDlg, HM_ADD, (WPARAM)idx, (LPARAM)dumpMsg->szModule);

			lw = (LOGWIN*)lModules.items[idx];
		}
		else
			lw = pActive;

		if (lw->hwnd)
			SendMessage(lw->hwnd, HM_DUMP, wParam, lParam);
		else
			PostMessage(hwndDlg, HM_DUMP, wParam, lParam); // loop msg until window will be ready

		return TRUE;
	}
	case HM_ADD:
	{
		// wParam = index, lParam = module name
		LOGWIN *lw;
		COLORREF col;
		TCITEM tci = {0};
		int idx = (int)wParam;
		char *str = (char*)lParam;

		if (!str) str = ""; // startup window

		lw = (LOGWIN*)mir_calloc( sizeof(LOGWIN));
		lw->Module = (char*)mir_strdup(str);
		List_Insert(&lModules, lw, idx);

		if (!gSingleMode && lParam)
		{
			tci.mask = TCIF_PARAM | TCIF_TEXT;
			tci.lParam = (LPARAM)lw;

			tci.pszText = mir_a2u(lw->Module);
			idx = TabCtrl_InsertItem(hTabs, tabCount, &tci);
			mir_free(tci.pszText);

			tabCount++;
		}

		GetClientRect(hTabs, &rcTabs);
		TabCtrl_AdjustRect(hTabs, FALSE, &rcTabs);

		CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_LOG), hwndDlg, LogDlgProc, (LPARAM)lw);
		ShowWindow(lw->hwnd, (tabCount > 1)?SW_HIDE:SW_SHOWNOACTIVATE);

		if (pActive)
		{
			col = ListView_GetBkColor(pActive->hList);
			ListView_SetBkColor(lw->hList, col);
			ListView_SetTextBkColor(lw->hList, col);

			col = ListView_GetTextColor(pActive->hList);
			ListView_SetTextColor(lw->hList, col);

			if (hfLogFont)
				SendMessage(lw->hList, WM_SETFONT, (WPARAM)hfLogFont, TRUE);
		}

		// hide startup window
		if (tabCount == 1)
		{
			ShowWindow(pActive->hwnd, SW_HIDE);
			PostMessage(pActive->hwnd, WM_CLOSE, 0, 0);
			pActive = lw;
		}

		if (!pActive)
			pActive = lw;

		return TRUE;
	}
	case HM_REMOVE:
	{
		// lParam = LOGWIN
		LOGWIN *lw = (LOGWIN*)lParam;

		if (!lw) break;

		if (lw == pActive)
		{
			int tab = TabCtrl_GetCurSel(hTabs);
			if (tab >= 0)
			{
				TCITEM tci={0};

				TabCtrl_DeleteItem(hTabs, tab);
				tabCount--;
				if (tabCount)
				{
					tab--;
					if (tab < 0 ) tab = 0;
					TabCtrl_SetCurSel(hTabs, tab);

					tci.mask = TCIF_PARAM;
					TabCtrl_GetItem(hTabs, tab, &tci);
					pActive = (LOGWIN*)tci.lParam;
					SendMessage(pActive->hwnd, WM_SIZE, 0, 0);
					ScrollDown(pActive);
					ShowWindow(pActive->hwnd, SW_SHOWNOACTIVATE);
					SetFocus(pActive->hList);
				}
				else
					pActive = NULL;
			}
		}

		List_RemovePtr(&lModules, lw);
		mir_free(lw->Module);
		mir_free(lw);
		return TRUE;
	}
	case HM_SETFONT:
	{
		// wParam = font, lParam = font color
		int i;
		LOGWIN *lw;
		for ( i = 0; i < lModules.realCount; i++ )
		{
			lw = (LOGWIN*)lModules.items[i];
			ListView_SetTextColor(lw->hList, (COLORREF)lParam);
			if (wParam)
				SendMessage(lw->hList, WM_SETFONT, wParam, TRUE);
		}
		return TRUE;
	}
	case HM_SETCOLOR:
	{
		// wParam = font, lParam = background color
		int i;
		LOGWIN *lw;
		for ( i = 0; i < lModules.realCount; i++ )
		{
			lw = (LOGWIN*)lModules.items[i];
			ListView_SetBkColor(lw->hList, (COLORREF)lParam);
			ListView_SetTextBkColor(lw->hList, (COLORREF)lParam);
			if (wParam)
				SendMessage(lw->hList, WM_SETFONT, wParam, TRUE);
		}
		return TRUE;
	}
	case HM_PAUSEALL:
	{
		// lParam = 1 to pause, 0 to start
		int i;
		LOGWIN *lw;
		for ( i = 0; i < lModules.realCount; i++ )
		{
			lw = (LOGWIN*)lModules.items[i];
			if (lw->Paused != (int)lParam)
				SendMessage(lw->hwnd, WM_COMMAND, IDC_PAUSE, 0);
		}
		return TRUE;
	}
	case HM_RESTART:
	{
		if (pActive)
		{
			pActive = NULL;
			PostMessage(hwndDlg, HM_RESTART, 0, 0);
			return TRUE;
		}
		// close all tabs
		if (!lParam)
		{
			LOGWIN *lw;
			TabCtrl_DeleteAllItems(hTabs);
			while ( lModules.realCount )
			{
				lw = (LOGWIN*)lModules.items[0];
				SendMessage(lw->hwnd, WM_CLOSE, 0, 0);
			}
			tabCount = 0;
			PostMessage(hwndDlg, HM_RESTART, 0, 1);
			return TRUE;
		}

		LoadSettings();
		SendMessage(hwndDlg, HM_ADD, 0, 0);
		PostMessage(hwndDlg, WM_SIZE, 0, 0);
		return TRUE;
	}
 	case WM_SETFOCUS:
		if (pActive) {
			SetFocus(pActive->hList);
		}
		return TRUE;
	case WM_NOTIFY:
		switch(wParam) {
		case IDC_TABS:
			{
				LPNMHDR lpnmhdr = (LPNMHDR)lParam;
				if (lpnmhdr->code == TCN_SELCHANGE)
				{
					int newTab = TabCtrl_GetCurSel(hTabs);
					if (newTab >= 0 )
					{
						TCITEM tci={0};
						HWND hOld = pActive->hwnd;

						tci.mask = TCIF_PARAM;

						if (!TabCtrl_GetItem(hTabs, newTab, &tci)) break;

						pActive = (LOGWIN*)tci.lParam;

						SendMessage(pActive->hwnd, WM_SIZE, 0, 0);
						ScrollDown(pActive);
						ShowWindow(hOld, SW_HIDE);
						ShowWindow(pActive->hwnd, SW_SHOWNOACTIVATE);
						SetFocus(pActive->hList);
					} else
						SendMessage(pActive->hwnd, WM_SIZE, 0, 0);
				}
				break;
			}
		}
		break;
	case WM_SIZE:
	{
		UTILRESIZEDIALOG urd={0};
		urd.cbSize=sizeof(urd);
		urd.hInstance=hInst;
		urd.hwndDlg=hwndDlg;
		urd.lpTemplate=MAKEINTRESOURCEA(IDD_CONSOLE);
		urd.pfnResizer=ConsoleResize;
		CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd);

		GetClientRect(hTabs, &rcTabs);
		TabCtrl_AdjustRect(hTabs, FALSE, &rcTabs);

		if ( pActive )
			SendMessage(pActive->hwnd, WM_SIZE, 0, 0);
		break;
	}
	case WM_GETMINMAXINFO:
	{
		MINMAXINFO *mmi=(MINMAXINFO*)lParam;
		mmi->ptMinTrackSize.x=400;
		mmi->ptMinTrackSize.y=200;
		break;
	}
	case WM_CLOSE:
		if ( lParam != 1 ) {
			Utils_SaveWindowPosition(hwndDlg,NULL,"Console","Console");
			ShowConsole(0);
			return TRUE;
		} else
			DestroyWindow(hwndDlg);
		break;
	case WM_DESTROY:
		pActive = NULL;
		if (hfLogFont) DeleteObject(hfLogFont);
		PostQuitMessage(0);
		break;
	}

	return FALSE;
}
Exemplo n.º 18
0
static LRESULT CALLBACK MButtonWndProc(HWND hwndDlg, UINT msg,  WPARAM wParam, LPARAM lParam)
{
	MButtonCtrl* bct =  (MButtonCtrl *)GetWindowLongPtr(hwndDlg, 0);
	switch(msg) {
	case WM_NCCREATE:
		SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) | BS_OWNERDRAW);
		bct = ( MButtonCtrl* )mir_calloc(sizeof(MButtonCtrl));
		if (bct==NULL) return FALSE;
		bct->hwnd = hwndDlg;
		bct->stateId = PBS_NORMAL;
		bct->hFont = ( HFONT )GetStockObject(DEFAULT_GUI_FONT);
		LoadTheme(bct);
		if (SUCCEEDED(CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, 
			IID_IAccPropServices, (void**)&bct->pAccPropServices))) 
		{
			// Annotating the Role of this object to be PushButton
			SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_PUSHBUTTON);
		} 
		else 
			bct->pAccPropServices = NULL;
		SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)bct);
		if (((CREATESTRUCT *)lParam)->lpszName) SetWindowText(hwndDlg, ((CREATESTRUCT *)lParam)->lpszName);
		return TRUE;

	case WM_DESTROY:
		if (bct) {
			if (bct->pAccPropServices) {
				bct->pAccPropServices->Release();
				bct->pAccPropServices = NULL;
			}
			if (bct->hwndToolTips) {
				TOOLINFO ti = {0};
				ti.cbSize = sizeof(ti);
				ti.uFlags = TTF_IDISHWND;
				ti.hwnd = bct->hwnd;
				ti.uId = (UINT_PTR)bct->hwnd;
				if (SendMessage(bct->hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti)) {
					SendMessage(bct->hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti);
				}
				if ( SendMessage(bct->hwndToolTips, TTM_GETTOOLCOUNT, 0, (LPARAM)&ti) == 0 ) {
					int idx;
					TTooltips tt;
					tt.ThreadId = GetCurrentThreadId();
			        
                    EnterCriticalSection(&csTips);
					if ( List_GetIndex( &lToolTips, &tt, &idx ) ) {
						mir_free( lToolTips.items[idx] );
						List_Remove( &lToolTips, idx );
						DestroyWindow( bct->hwndToolTips );
					}
			        LeaveCriticalSection(&csTips);
					
                    bct->hwndToolTips = NULL;
				}
			}
			if (bct->arrow) IconLib_ReleaseIcon(bct->arrow, 0);
			DestroyTheme(bct);
		}
		break;	// DONT! fall thru

    case WM_NCDESTROY:
		mir_free(bct);
        break;

	case WM_SETTEXT:
		bct->cHot = 0;
		if ( lParam != 0 ) {
			TCHAR *tmp = ( TCHAR* )lParam;
			while (*tmp) {
				if (*tmp=='&' && *(tmp+1)) {
					bct->cHot = _tolower(*(tmp+1));
					break;
				}
				tmp++;
			}
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		break;

	case WM_KEYUP:
		if (bct->stateId!=PBS_DISABLED && wParam == VK_SPACE) {
			if (bct->pushBtn) {
				if (bct->pbState) {
					bct->pbState = 0;
					bct->stateId = PBS_NORMAL;
				}
				else {
					bct->pbState = 1;
					bct->stateId = PBS_PRESSED;
				}
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
			return 0;
		}
		break;

	case WM_SYSKEYUP:
		if (bct->stateId!=PBS_DISABLED && bct->cHot && bct->cHot == tolower((int)wParam)) {
			if (bct->pushBtn) {
				if (bct->pbState) {
					bct->pbState = 0;
					bct->stateId = PBS_NORMAL;
				}
				else {
					bct->pbState = 1;
					bct->stateId = PBS_PRESSED;
				}
				InvalidateRect(bct->hwnd, NULL, TRUE);
			}
			SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
			return 0;
		}
		break;

	case WM_THEMECHANGED:
		// themed changed, reload theme object
		LoadTheme(bct);
		InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it
		break;

	case WM_SETFONT: // remember the font so we can use it later
		bct->hFont = (HFONT)wParam; // maybe we should redraw?
		break;

	case WM_NCPAINT:
	case WM_PAINT:
	{
		PAINTSTRUCT ps;
		HDC hdcPaint;

		hdcPaint = BeginPaint(hwndDlg, &ps);
		if (hdcPaint) {
			PaintWorker(bct, hdcPaint);
			EndPaint(hwndDlg, &ps);
		}
		break;
	}
	case BM_SETIMAGE:
	{
		HGDIOBJ hnd = NULL;
		if (bct->hIcon) hnd = bct->hIcon;
		else if (bct->hBitmap) hnd = bct->hBitmap;

		if (wParam == IMAGE_ICON) {
			bct->hIcon = (HICON)lParam;
			bct->hBitmap = NULL;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		else if (wParam == IMAGE_BITMAP) {
			bct->hBitmap = (HBITMAP)lParam;
			bct->hIcon = NULL;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		return (LRESULT)hnd;
	}
	case BM_GETIMAGE:
		if (bct->hIcon) return (LRESULT)bct->hIcon;
		else if (bct->hBitmap) return (LRESULT)bct->hBitmap;
		else return 0;
	case BM_SETCHECK:
		if (!bct->pushBtn) break;
		if (wParam == BST_CHECKED) {
			bct->pbState = 1;
               bct->stateId = PBS_PRESSED;
		}
		else if (wParam == BST_UNCHECKED) {
			bct->pbState = 0;
               bct->stateId = PBS_NORMAL;
		}
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BM_GETCHECK:
		if (bct->pushBtn) {
			return bct->pbState?BST_CHECKED:BST_UNCHECKED;
		}
		return 0;
	case BUTTONSETARROW: // turn arrow on/off
		if (wParam) {
			if (!bct->arrow) {
				bct->arrow = LoadSkinIcon(SKINICON_OTHER_DOWNARROW);
				SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_BUTTONDROPDOWN);
			}
		}
		else {
			if (bct->arrow) {
				IconLib_ReleaseIcon(bct->arrow, 0);
				bct->arrow = NULL;
				SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_PUSHBUTTON);
			}
		}
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BUTTONSETDEFAULT:
		bct->defbutton = wParam?1:0;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BUTTONSETASPUSHBTN:
		bct->pushBtn = 1;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BUTTONSETASFLATBTN:
		bct->flatBtn = 1;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;
	case BUTTONADDTOOLTIP:
		if ( wParam ) {
			TOOLINFO ti = {0};
			if ( !bct->hwndToolTips ) {
				int idx;
				TTooltips tt;
				tt.ThreadId = GetCurrentThreadId();
			    
                EnterCriticalSection(&csTips);
				if ( List_GetIndex( &lToolTips, &tt, &idx )) {
					bct->hwndToolTips = ((TTooltips*)lToolTips.items[idx])->hwnd;
				} else {
					TTooltips *ptt = ( TTooltips* )mir_alloc( sizeof(TTooltips) );
					ptt->ThreadId = tt.ThreadId;
					ptt->hwnd = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), TTS_ALWAYSTIP, 0, 0, 0, 0, NULL, NULL, hMirandaInst, NULL);
					List_Insert( &lToolTips, ptt, idx );
					bct->hwndToolTips = ptt->hwnd;
				}
    			LeaveCriticalSection(&csTips);
			}
			ti.cbSize = sizeof(ti);
			ti.uFlags = TTF_IDISHWND;
			ti.hwnd = bct->hwnd;
			ti.uId = (UINT_PTR)bct->hwnd;
			if (SendMessage(bct->hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti))
				SendMessage(bct->hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti);
			ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS;
			ti.uId = (UINT_PTR)bct->hwnd;
			#if defined( _UNICODE )
				if ( lParam & BATF_UNICODE )
					ti.lpszText = mir_wstrdup( TranslateW(( WCHAR* )wParam ));
				else
					ti.lpszText = LangPackPcharToTchar(( char* )wParam );
			#else
				ti.lpszText = Translate(( char* )wParam );
			#endif
			if (bct->pAccPropServices) {
				wchar_t *tmpstr = mir_t2u(ti.lpszText);
				bct->pAccPropServices->SetHwndPropStr(bct->hwnd, OBJID_CLIENT, 
					CHILDID_SELF, PROPID_ACC_DESCRIPTION, tmpstr);
				mir_free(tmpstr);
			}
			SendMessage( bct->hwndToolTips, TTM_ADDTOOL, 0, (LPARAM)&ti);
			#if defined( _UNICODE )
				mir_free( ti.lpszText );
			#endif
		}
		break;
	case WM_SETFOCUS: // set keybord focus and redraw
		bct->focus = 1;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;

	case WM_KILLFOCUS: // kill focus and redraw
		bct->focus = 0;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;

	case WM_WINDOWPOSCHANGED:
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;

	case WM_ENABLE: // windows tells us to enable/disable
		bct->stateId = wParam?PBS_NORMAL:PBS_DISABLED;
		InvalidateRect(bct->hwnd, NULL, TRUE);
		break;

	case WM_MOUSELEAVE: // faked by the WM_TIMER
		if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled
			bct->stateId = PBS_NORMAL;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		break;

	case WM_LBUTTONDOWN:
		if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled
			bct->stateId = PBS_PRESSED;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		break;

	case WM_LBUTTONUP:
    {
        int showClick = 0;
		if (bct->pushBtn) {
			if (bct->pbState) bct->pbState = 0;
			else bct->pbState = 1;
		}
		if (bct->stateId!=PBS_DISABLED) { // don't change states if disabled
            if (bct->stateId==PBS_PRESSED)
                showClick = 1;
			if (msg==WM_LBUTTONUP) bct->stateId = PBS_HOT;
			else bct->stateId = PBS_NORMAL;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
        if (showClick) // Tell your daddy you got clicked.
            SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndDlg), BN_CLICKED), (LPARAM)hwndDlg);
		break;
    }
	case WM_MOUSEMOVE:
		if (bct->stateId == PBS_NORMAL) {
			bct->stateId = PBS_HOT;
			InvalidateRect(bct->hwnd, NULL, TRUE);
		}
		// Call timer, used to start cheesy TrackMouseEvent faker
		SetTimer(hwndDlg,BUTTON_POLLID,BUTTON_POLLDELAY,NULL);
		break;
	case WM_TIMER: // use a timer to check if they have did a mouseout
		if (wParam == BUTTON_POLLID) {
			RECT rc;
			POINT pt;
			GetWindowRect(hwndDlg,&rc);
			GetCursorPos(&pt);
			if(!PtInRect(&rc,pt)) { // mouse must be gone, trigger mouse leave
				PostMessage(hwndDlg,WM_MOUSELEAVE,0,0L);
				KillTimer(hwndDlg,BUTTON_POLLID);
		}	}
		break;

	case WM_ERASEBKGND:
		return 1;
	}
	return DefWindowProc(hwndDlg, msg, wParam, lParam);
}
Exemplo n.º 19
0
int main() {

	List list, list2;
	size_t dummy = 0x1234;
	int i = 0;

	Node *test;

	List_Init(&list);
	assert(list.last == NULL);
	assert(list.first == NULL);
	assert(list.size == 0);
	assert(list.index == 0);


	List_InsertAfter(&list, (void *) dummy, int2str(++i));
	assert(list.current == list.first);
	assert(list.current == list.last);
	assert(list.last != NULL);
	assert(list.first != NULL);
	assert(list.last->next == NULL);
	assert(list.first->prev == NULL);

	assert(list.size == i);
	assert(eq(list.current->name, "1"));

	List_InsertAfter(&list, (void *) dummy, int2str(++i));
	assert(list.current->prev == list.first);
	assert(list.current == list.last);
	assert(list.last->next == NULL);
	assert(list.first->prev == NULL);
	assert(list.size == i);
	assert(eq(list.current->name, "2"));

	List_InsertAfter(&list, (void *) dummy, int2str(++i));
	assert(list.current->prev->prev == list.first);
	assert(list.current == list.last);
	assert(list.last->next == NULL);
	assert(list.first->prev == NULL);
	assert(list.size == i);
	assert(eq(list.current->name, "3"));

	List_Remove(&list);
	assert(list.current->prev == list.first);
	assert(list.current == list.last);
	assert(list.last->next == NULL);
	assert(list.first->prev == NULL);
	assert(list.size == i - 1);
	assert(eq(list.current->name, "2"));

	List_InsertBefore(&list, (void *) dummy, int2str(++i));
	assert(list.current != list.last);
	assert(list.current->next == list.last);

	assert(list.last->next == NULL);
	assert(list.first->prev == NULL);
	assert(list.size == i - 1);
	assert(eq(list.current->name, "4"));
	assert(eq(list.last->name, "2"));

	List_GotoFirst(&list);
	List_InsertBefore(&list, (void *) dummy, int2str(++i));
	assert(list.current == list.first);
	assert(list.last->next == NULL);
	assert(list.first->prev == NULL);
	assert(list.size == i - 1);
	assert(eq(list.current->name, "5"));
	assert(eq(list.last->name, "2"));

	List_InsertAfter(&list, (void *) dummy, int2str(++i));
	assert(list.current == list.first->next);
	assert(list.current->prev == list.first);
	assert(list.current->next->prev == list.current);
	assert(list.last->next == NULL);
	assert(list.first->prev == NULL);
	assert(list.size == i - 1);
	assert(eq(list.current->name, "6"));
	assert(eq(list.last->name, "2"));

	List_GotoFirst(&list);
	assert(list.current == list.first);
	test = list.first->next;
	List_Remove(&list);
	assert(list.first == test);
	assert(list.current == list.first);
	assert(list.last->next == NULL);
	assert(list.first->prev == NULL);
	assert(list.size == i - 2);
	//assert(eq(list.current->name, "7"));
	assert(eq(list.last->name, "2"));

	List_GotoFirst(&list);
	assert(list.current == list.first);

	List_Copy(&list2, &list);
	assert(list2.size == list.size);
	assert(list2.current == list2.first);
	assert(eq(list2.last->name, "2"));

	List_GotoLast(&list);
	assert(list.current == list.last);

	List_Copy(&list2, &list);
	assert(list2.current == list2.last);
	assert(list2.size == list.size);
	assert(list2.index == list.index);
	assert(list2.index == 0);
	assert(eq(list2.last->name, "2"));
	assert(eq(list2.last->name, list.last->name));
	assert(eq(list2.first->name, list.first->name));
	assert(eq(list2.current->name, list.current->name));
	assert(eq(list2.current->prev->name, list.current->prev->name));
	assert(list2.current->next == list.current->next);
	assert(list.current->next == 0);
	List_GotoFirst(&list);
	assert(!eq(list2.current->name, list.current->name));
	List_GotoFirst(&list2);
	assert(eq(list2.current->name, list.current->name));
	assert(list.current == list.first);
	assert(list.current->prev == NULL);
	assert(list2.current->prev == NULL);


	List_InsertAfter(&list, (void *) 0xDEADBEEF, int2str(++i));
	assert(list.first->next->value == (void *) 0xDEADBEEF);
	assert(list.current = list.first->next);

	List_InsertAfter(&list, (void *) dummy, int2str(++i));

	List_InsertBefore(&list, (void *) dummy, int2str(++i));
	List_InsertBefore(&list, (void *) dummy, int2str(++i));
	List_InsertBefore(&list, (void *) dummy, int2str(++i));
	assert(list.size == i - 2);	// i = 11
	List_GotoFirst(&list);
	List_GotoNext(&list);
	List_GotoPrevious(&list);

	List_GotoLast(&list);

	test = list.last;
	assert(list.current == list.last);

	List_Remove(&list);
	assert(list.last != test);
	assert(list.current == list.last);

	List_Remove(&list);
	assert(list.current == list.last);

	List_Remove(&list);
	assert(list.current == list.last);

	List_Remove(&list);

	assert(list.current == list.last);
	assert(list.size == i - 6);

	List_GotoPrevious(&list);
	List_GotoPrevious(&list);
	List_GotoPrevious(&list);

	assert(List_Retrieve(&list) == (void *) 0xDEADBEEF);
	List_Remove(&list);
	assert(!List_Includes(&list, (void *) 0xDEADBEEF));
	assert(list.size == i - 7);

	List_GotoLast(&list);
	List_InsertAfter(&list, (void *) 0xDEADBEEF, int2str(++i));

#ifdef USE_INDEX
	List_CreateIndices(&list);
	assert(list.mindices);
	assert(List_GetIndex(&list) == list.size - 1);
	assert(List_GetNodeIndex(&list, list.first) == 0);
	assert(List_GetNodeIndex(&list, list.last->prev) == list.size - 2);
	assert(List_GetNodeIndex(&list, list.last->prev->prev) == list.size - 3);
	assert(list.mindices[ptrhash((void *) 0xDEADBEEF)]);
#endif
	assert(List_Includes(&list, (void *) 0xDEADBEEF));

	assert(list.current == list.last);
	assert(List_Retrieve(&list) == (void *) 0xDEADBEEF);

	List_Update(&list, (void *) 0xDEADC0DE);
	assert(list.current == list.last);
	assert(List_Retrieve(&list) == (void *) 0xDEADC0DE);
	assert(!List_Includes(&list, (void *) 0xDEADBEEF));
	assert(List_Includes(&list, (void *) 0xDEADC0DE));
#ifdef USE_INDEX
	assert(list.mindices);
	assert(list.mindices[ptrhash((void *) 0xDEADC0DE)]);
#endif
	List_Remove(&list);
	assert(!List_Includes(&list, (void *) 0xDEADC0DE));
#ifdef USE_INDEX
	assert(list.mindices);
	assert(ptrhash((void *) dummy) != ptrhash((void *) 0xDEADC0DE));
	assert(ptrhash((void *) dummy) != ptrhash((void *) 0xDEADBEEF));
	// disable temporary
	assert(list.mindices[ptrhash((void *) 0xDEADC0DE)]);
	assert(list.mindices[ptrhash((void *) 0xDEADC0DE)]->nodes[0] == NULL);
	assert(list.mindices[ptrhash((void *) 0xDEADC0DE)]->used == 0);
	// dead beef was updated, so used must be still 1
	assert(list.mindices[ptrhash((void *) 0xDEADBEEF)]);
	assert(list.mindices[ptrhash((void *) 0xDEADBEEF)]->nodes[0] == NULL);
	assert(list.mindices[ptrhash((void *) 0xDEADBEEF)]->used == 1);
#endif

	List_Clear(&list);
	assert(list.size == 0);
	List_Init(&list);
	i = 0;

	List_InsertBefore(&list, (void *) dummy, int2str(++i));
	List_InsertBefore(&list, (void *) dummy, int2str(++i));
	List_InsertBefore(&list, (void *) dummy, int2str(++i));
	assert(list.size == 3);
	List_Remove(&list);
	List_Remove(&list);
	List_Remove(&list);
	List_Remove(&list);
	List_GotoFirst(&list);

	List_Clear(&list);

	// testing the order of removal is equivalent to gotonext
	List_Init(&list);
	List_InsertAfter(&list, (void *) 1, NULL);
	List_InsertAfter(&list, (void *) 2, NULL);
	List_InsertAfter(&list, (void *) 3, NULL);
	List_InsertAfter(&list, (void *) 4, NULL);
	List_GotoFirst(&list);
	assert(list.current->value == (void *) 1);
	List_GotoNext(&list);
	assert(list.current->value == (void *) 2);
	List_GotoNext(&list);
	assert(list.current->value == (void *) 3);
	List_GotoNext(&list);
	assert(list.current->value == (void *) 4);
	assert(list.current == list.last);
	List_GotoFirst(&list);
	assert(list.current->value == (void *) 1);
	List_Remove(&list);
	assert(list.current->value == (void *) 2);
	List_Remove(&list);
	assert(list.current->value == (void *) 3);
	List_Remove(&list);
	assert(list.current->value == (void *) 4);
	assert(list.current == list.last);
	List_Remove(&list);
	assert(list.current == list.last);
	assert(list.current == list.first);
	assert(list.current == NULL);


	freemem();
	return 0;
}