Пример #1
0
ResultType WinGroup::Deactivate(bool aStartWithMostRecent)
{
	if (IsEmpty())
		return OK;  // OK since this is the expected behavior in this case.
	// Otherwise:
	if (!Update(false)) // Update our private member vars.
		return FAIL;  // It already displayed the error for us.

	HWND active_window = GetForegroundWindow();
	if (IsMember(active_window, *g))
		sAlreadyVisitedCount = 0;

	// Activate the next unvisited non-member:
	WindowSearch ws;
	ws.mFindLastMatch = !aStartWithMostRecent || sAlreadyVisitedCount;
	ws.mAlreadyVisited = sAlreadyVisited;
	ws.mAlreadyVisitedCount = sAlreadyVisitedCount;
	ws.mFirstWinSpec = mFirstWindow;

	EnumWindows(EnumParentFindAnyExcept, (LPARAM)&ws);

	if (ws.mFoundParent)
	{
		// If the window we're about to activate owns other visble parent windows, it can
		// never truly be activated because it must always be below them in the z-order.
		// Thus, instead of activating it, activate the first (and usually the only?)
		// visible window that it owns.  Doing this makes things nicer for some apps that
		// have a pair of main windows, such as MS Visual Studio (and probably many more),
		// because it avoids activating such apps twice in a row as the user progresses
		// through the sequence:
		HWND first_visible_owned = WindowOwnsOthers(ws.mFoundParent);
		if (first_visible_owned)
		{
			MarkAsVisited(ws.mFoundParent);  // Must mark owner as well as the owned window.
			// Activate the owned window instead of the owner because it usually
			// (probably always, given the comments above) is the real main window:
			ws.mFoundParent = first_visible_owned;
		}
		SetForegroundWindowEx(ws.mFoundParent);
		// Probably best to do this before WinDelay in case another hotkey fires during the delay:
		MarkAsVisited(ws.mFoundParent);
		DoWinDelay;
	}
	else // No window was found to activate (they have all been visited).
	{
		if (sAlreadyVisitedCount)
		{
			bool wrap_around = (sAlreadyVisitedCount > 1);
			sAlreadyVisitedCount = 0;
			if (wrap_around)
			{
				// The user pressed a hotkey to do something, yet nothing has happened yet.
				// We want something to happen every time if there's a qualifying
				// "something" that we can do.  And in this case there is: we can start
				// over again through the list, excluding the foreground window (which
				// the user has already had a chance to review):
				MarkAsVisited(active_window);
				// Make a recursive call to self.  This can't result in an infinite
				// recursion (stack fault) because the called layer will only
				// recurse a second time if sAlreadyVisitedCount > 1, which is
				// impossible with the current logic:
				Deactivate(false); // Seems best to ignore aStartWithMostRecent in this case?
			}
		}
	}
	// Even if a window wasn't found, we've done our job so return OK:
	return OK;
}
Пример #2
0
VALUE DetermineZeroValue(POSITION position)
{
	POSITION i,lowSeen,highSeen;
	POSITION numUndecided, oldNumUndecided, numNew;
	MOVELIST *moveptr, *headMove;
	POSITION child;
	VALUE childValue;
	POSITION numTot, numWin, numTie;
	int tieRemoteness, winRemoteness;

	//if (gTwoBits)
	//    InitializeVisitedArray();

	StoreValueOfPosition(position,Primitive(position));
	MarkAsVisited(position);
	oldNumUndecided = 0;
	numUndecided = 1;
	numNew = 1;

	lowSeen = position;
	highSeen = lowSeen+1;

	while((numUndecided != oldNumUndecided) || (numNew != 0)) {

		oldNumUndecided = numUndecided;
		numUndecided = 0;
		numNew = 0;
		for(i = lowSeen; i <= highSeen; i++) {
			if(Visited(i)) {
				if(GetValueOfPosition(i) == undecided) {
					moveptr = headMove = GenerateMoves(i);
					numTot = numWin = numTie = 0;
					tieRemoteness = winRemoteness = REMOTENESS_MAX;
					while(moveptr != NULL) {
						child = DoMove(i,moveptr->move);
						numTot++;
						if(Visited(child))
							childValue = GetValueOfPosition(child);
						else{
							childValue = Primitive(child);
							numNew++;
							MarkAsVisited(child);
							StoreValueOfPosition(child,childValue);
							if(childValue != undecided) {
								SetRemoteness(child,0);
							}
							if(child < lowSeen) lowSeen = child;
							if(child > highSeen) highSeen = child + 1;
						}

						if(childValue == lose) {
							StoreValueOfPosition(i,win);
							if(Remoteness(i) > Remoteness(child)+1)
								SetRemoteness(i,Remoteness(child)+1);
						}

						if(childValue == win) {
							numWin++;
							if(Remoteness(child) < winRemoteness) {
								winRemoteness = Remoteness(child);
							}
						}
						if(childValue == tie) {
							numTie++;
							if(Remoteness(child) < tieRemoteness) {
								tieRemoteness = Remoteness(child);
							}
						}

						moveptr = moveptr->next;
					}
					FreeMoveList(headMove);
					if((numTot != 0) && (numTot == numWin + numTie)) {
						if(numTie == 0) {
							SetRemoteness(i, winRemoteness+1);
							StoreValueOfPosition(i,lose);
						}else{
							SetRemoteness(i, tieRemoteness+1);
							StoreValueOfPosition(i,tie);
						}
					}

					if(GetValueOfPosition(i) == undecided)
						numUndecided++;
				}
			}
		}

		printf("\nnumUndecided: " POSITION_FORMAT ", diff: " POSITION_FORMAT ", numNew: " POSITION_FORMAT
		       ", lowSeen: " POSITION_FORMAT ", highSeen: " POSITION_FORMAT,
		       numUndecided,numUndecided - oldNumUndecided,numNew,lowSeen,highSeen);

	}

	for(i = 0; i < gNumberOfPositions; i++) {
		if(Visited(i) && (GetValueOfPosition(i) == undecided)) {
			SetRemoteness(i,REMOTENESS_MAX);
			StoreValueOfPosition(i, tie);
		}
		UnMarkAsVisited(i);
	}

	return GetValueOfPosition(position);
}
Пример #3
0
ResultType WinGroup::Activate(bool aStartWithMostRecent, WindowSpec *aWinSpec, Label **aJumpToLabel)
{
	if (aJumpToLabel) // Initialize early in case of early return.
		*aJumpToLabel = NULL;
	if (IsEmpty())
		return OK;  // OK since this is the expected behavior in this case.
	// Otherwise:
	if (!Update(true)) // Update our private member vars.
		return FAIL;  // It already displayed the error for us.
	WindowSpec *win, *win_to_activate_next = aWinSpec;
	bool group_is_active = false; // Set default.
	HWND activate_win, active_window = GetForegroundWindow(); // This value is used in more than one place.
	if (win_to_activate_next)
	{
		// The caller told us which WindowSpec to start off trying to activate.
		// If the foreground window matches that WindowSpec, do nothing except
		// marking it as visited, because we want to stay on this window under
		// the assumption that it was newly revealed due to a window on top
		// of it having just been closed:
		if (win_to_activate_next == IsMember(active_window, *g))
		{
			group_is_active = true;
			MarkAsVisited(active_window);
			return OK;
		}
		// else don't mark as visited even if it's a member of the group because
		// we're about to attempt to activate a different window: the next
		// unvisited member of this same WindowSpec.  If the below doesn't
		// find any of those, it continue on through the list normally.
	}
	else // Caller didn't tell us which, so determine it.
	{
		if (win_to_activate_next = IsMember(active_window, *g)) // Foreground window is a member of this group.
		{
			// Set it to activate this same WindowSpec again in case there's
			// more than one that matches (e.g. multiple notepads).  But first,
			// mark the current window as having been visited if it hasn't
			// already by marked by a prior iteration.  Update: This method
			// doesn't work because if a unvisted matching window became the
			// foreground window by means other than using GroupActivate
			// (e.g. launching a new instance of the app: now there's another
			// matching window in the foreground).  So just call it straight
			// out.  It has built-in dupe-checking which should prevent the
			// list from filling up with dupes if there are any special
			// situations in which that might otherwise happen:
			//if (!sAlreadyVisitedCount)
			group_is_active = true;
			MarkAsVisited(active_window);
		}
		else // It's not a member.
		{
			win_to_activate_next = mFirstWindow;  // We're starting fresh, so start at the first window.
			// Reset the list of visited windows:
			sAlreadyVisitedCount = 0;
		}
	}

	// Activate any unvisited window that matches the win_to_activate_next spec.
	// If none, activate the next window spec in the series that does have an
	// existing window:
	// If the spec we're starting at already has some windows marked as visited,
	// set this variable so that we know to retry the first spec again in case
	// a full circuit is made through the window specs without finding a window
	// to activate.  Note: Using >1 vs. >0 might protect against any infinite-loop
	// conditions that may be lurking:
	bool retry_starting_win_spec = (sAlreadyVisitedCount > 1);
	bool retry_is_in_effect = false;
	for (win = win_to_activate_next;;)
	{
		// Call this in the mode to find the last match, which  makes things nicer
		// because when the sequence wraps around to the beginning, the windows will
		// occur in the same order that they did the first time, rather than going
		// backwards through the sequence (which is counterintuitive for the user):
		if (   activate_win = WinActivate(*g, win->mTitle, win->mText, win->mExcludeTitle, win->mExcludeText
			// This next line is whether to find last or first match.  We always find the oldest
			// (bottommost) match except when the user has specifically asked to start with the
			// most recent.  But it only makes sense to start with the most recent if the
			// group isn't currently active (i.e. we're starting fresh), because otherwise
			// windows would be activated in an order different from what was already shown
			// the first time through the enumeration, which doesn't seem to be ever desirable:
			, !aStartWithMostRecent || group_is_active
			, sAlreadyVisited, sAlreadyVisitedCount)   )
		{
			// We found a window to activate, so we're done.
			// Probably best to do this before WinDelay in case another hotkey fires during the delay:
			MarkAsVisited(activate_win);
			DoWinDelay;
			//MsgBox(win->mText, 0, win->mTitle);
			break;
		}
		// Otherwise, no window was found to activate.
		if (retry_is_in_effect)
			// This was the final attempt because we've already gone all the
			// way around the circular linked list of WindowSpecs.  This check
			// must be done, otherwise an infinite loop might result if the windows
			// that formed the basis for determining the value of
			// retry_starting_win_spec have since been destroyed:
			break;
		// Otherwise, go onto the next one in the group:
		win = win->mNextWindow;
        // Even if the above didn't change the value of <win> (because there's only
		// one WinSpec in the list), it's still correct to reset this count because
		// we want to start the fresh again after all the windows have been
		// visited.  Note: The only purpose of sAlreadyVisitedCount as used by
		// this function is to indicate which windows in a given WindowSpec have
		// been visited, not which windows altogether (i.e. it's not necessary to
		// remember which windows have been visited once we move on to a new
		// WindowSpec).
		sAlreadyVisitedCount = 0;
		if (win == win_to_activate_next)
		{
			// We've made one full circuit of the circular linked list without
			// finding an existing window to activate. At this point, the user
			// has pressed a hotkey to do a GroupActivate, but nothing has happened
			// yet.  We always want something to happen unless there's absolutely
			// no existing windows to activate, or there's only a single window in
			// the system that matches the group and it's already active.
			if (retry_starting_win_spec)
			{
				// Mark the foreground window as visited so that it won't be
				// mistakenly activated again by the next iteration:
				MarkAsVisited(active_window);
				retry_is_in_effect = true;
				// Now continue with the next iteration of the loop so that it
				// will activate a different instance of this WindowSpec rather
				// than getting stuck on this one.
			}
			else 
			{
				if (aJumpToLabel && mJumpToLabel)
				{
					// Caller asked us to return in this case, so that it can
					// use this value to execute a user-specified Gosub:
					*aJumpToLabel = mJumpToLabel;  // Set output param for the caller.
				}
				return FAIL; // Let GroupActivate set ErrorLevel to indicate what happened.
			}
		}
	}
	return OK;
}
Пример #4
0
void WriteNode(FILE *fp, POSITION node, int level, EDGELIST *tree) {
	OPEN_POS_DATA pdata;
	REMOTENESS nodeRemoteness;
	char label[50];

	if(kLoopy && gUseOpen) {
		pdata = GetOpenData(node);
	} else {
		pdata = 0;
	}

	if(!Visited(node)) {
		if(level != GetLevelNumber(pdata)) {
			fprintf(fp, "\t\tsubgraph cluster%llu {\n", node);
			fprintf(fp, "\t\t\tlabel = \" \"\n");
			fprintf(fp, "\t\t\tcolor = \"blue\"\n\t");
			sprintf(label, "\\nlvl %d", GetLevelNumber(pdata));
		} else {
			sprintf(label, " ");
		}

		if(node == gInitialPosition) {
			if(level == GetLevelNumber(pdata)) {
				fprintf(fp, "\t\tsubgraph cluster%llu {\n", node);
				fprintf(fp, "\t\t\tcolor = \"blue\"\n\t");
			}
			fprintf(fp, "%slabel = \"Initial Position\"\n\t", (level == GetLevelNumber(pdata)) ? "\t\t\t" : "\t\t");
		}

		if(GetLevelNumber(pdata) == 0) {
			MarkAsVisited(node);
			fprintf(fp, "\t\t%llu [color = \"%s\", style = \"filled\", shape = \"%s\", label = \"%llu%s\"]", node, PositionColor(node), PositionShape(node), node, label);
		} else if(GetLevelNumber(pdata) > 0) {
			MarkAsVisited(node);
			fprintf(fp, "\t\t%llu [color = \"%s\", style = \"filled\", peripheries = %d, shape = \"%s\", label = \"%llu%s\"]", node, PositionColor(node), GetCorruptionLevel(pdata) + 1, PositionShape(node), node, label);
		} else {
			BadElse("WriteNode");
		}

		if(level != GetLevelNumber(pdata) || node == gInitialPosition) {
			fprintf(fp, "\n\t\t}\n");
		} else {
			fprintf(fp, "\n");
		}

		/* Determine rank of node */
		if(GetLevelNumber(pdata) == 0) {
			nodeRemoteness = Remoteness(node);
		} else {
			nodeRemoteness = GetFremoteness(pdata);
		}

		//0-REMOTENESS_MAX-1 regular nodes,
		//REMOTENESS_MAX level above current level,
		//REMOTENESS_MAX+1 level below current level
		if(gRemotenessOrder) {
			if(level == GetLevelNumber(pdata)) {
				if(GetFringe(pdata)) {
					UpdateRankList(tree, node, REMOTENESS_MAX+1); // want fringes at bottom
				} else {
					UpdateRankList(tree, node, nodeRemoteness);
				}
			} else if(level > GetLevelNumber(pdata)) {
				UpdateRankList(tree, node, REMOTENESS_MAX+1);
			} else if(level < GetLevelNumber(pdata)) {
				UpdateRankList(tree, node, REMOTENESS_MAX);
			} else {
				BadElse("WriteNode");
			}
		}
	}
}