• R/O
  • HTTP
  • SSH
  • HTTPS

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

ショートカットキーでVTウィンドウの位置を動かせるようにします。


File Info

Révision 0ef0c5216739c932b0add39c33dd272f866bd494
Taille 9,528 octets
l'heure 2015-11-20 11:50:44
Auteur IWAMOTO Kouichi
Message de Log

LICENSEを追加

Content

/*
 * Copyright (c) 2015 IWAMOTO Kouichi
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "teraterm.h"
#include "tttypes.h"
#include "ttplugin.h"
#include "tt_res.h"
#include "ttcommon.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>

#include "compat_w95.h"

#define ORDER 5950
#define SECTION "TTXSetPosition"

#define ID_MOVE_UP           55400
#define ID_MOVE_DOWN         55401
#define ID_MOVE_LEFT         55402
#define ID_MOVE_RIGHT        55403
#define ID_MOVE_TOP          55404
#define ID_MOVE_BOTTOM       55405
#define ID_MOVE_MLEFT        55406
#define ID_MOVE_MRIGHT       55407
#define ID_MOVE_TOPLEFT      55408
#define ID_MOVE_TOPRIGHT     55409
#define ID_MOVE_BOTTOMLEFT   55410
#define ID_MOVE_BOTTOMRIGHT  55411

#define DIR_DECREASE   0
#define DIR_INCREASE   1
#define DIR_VERTICAL   0
#define DIR_HORIZONTAL 2
#define DIR_ROOTONLY   4

#define DIR_UP         0
#define DIR_DOWN       1
#define DIR_LEFT       2
#define DIR_RIGHT      3

static HANDLE hInst; /* Instance handle of TTX*.DLL */

typedef struct {
	PTTSet ts;
	PComVar cv;
	BOOL MultiMonitorSupported;
} TInstVar;

static TInstVar FAR * pvar;

/* WIN32 allows multiple instances of a DLL */
static TInstVar InstVar;

typedef struct {
	int delta;
	int dir;
	RECT crect;
	RECT trect;
	int edge;
} GetDeltaParam;

static void PASCAL FAR TTXInit(PTTSet ts, PComVar cv) {
	OSVERSIONINFO osvi;

	pvar->ts = ts;
	pvar->cv = cv;

	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&osvi);
	if ((osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 4) ||
	    (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && osvi.dwMinorVersion < 10)) {
		pvar->MultiMonitorSupported = FALSE;
	}
	else {
		pvar->MultiMonitorSupported = TRUE;
	}
}

#define swap(a, b)	(a^=b, b^=a, a^=b)
void GetDelta(GetDeltaParam *d) {
	int cpos1, cpos2, tpos1, tpos2;

	if (d->dir & DIR_HORIZONTAL) {
		cpos1 = d->crect.left;
		cpos2 = d->crect.right;
		tpos1 = d->trect.left;
		tpos2 = d->trect.right;
	}
	else {
		cpos1 = d->crect.top;
		cpos2 = d->crect.bottom;
		tpos1 = d->trect.top;
		tpos2 = d->trect.bottom;
	}

	if ((d->dir & DIR_INCREASE) == 0) {
		swap(cpos1, tpos1);
		swap(cpos2, tpos2);
	}

	if (cpos1 < tpos1) {
		if (d->delta == 0 || d->delta > tpos1 - cpos1) {
			d->delta = tpos1 - cpos1;
		}
	}
	else if (cpos1 < tpos2) {
		if (d->delta == 0 || d->delta > tpos2 - cpos1) {
			d->delta = tpos2 - cpos1;
		}
	}
	if (cpos2 < tpos1) {
		if (d->delta == 0 || d->delta > tpos1 - cpos2) {
			d->delta = tpos1 - cpos2;
		}
	}
	else if (cpos2 < tpos2) {
		if (d->delta == 0 || d->delta > tpos2 - cpos2) {
			d->delta = tpos2 - cpos2;
		}
	}
}

BOOL CALLBACK MonitorEnumProc(HMONITOR hMon, HDC hdcMon, LPRECT rect, LPARAM data) {
	MONITORINFO mon;
	GetDeltaParam *d = (GetDeltaParam *)data;

	mon.cbSize = sizeof(MONITORINFO);
	GetMonitorInfo(hMon, &mon);

	switch (d->dir & (~DIR_ROOTONLY)) {
	  case DIR_UP:
		if (d->edge > mon.rcWork.top) {
			d->edge = mon.rcWork.top;
		}
		break;
	  case DIR_DOWN:
		if (d->edge < mon.rcWork.bottom) {
			d->edge = mon.rcWork.bottom;
		}
		break;
	  case DIR_LEFT:
		if (d->edge > mon.rcWork.left) {
			d->edge = mon.rcWork.left;
		}
		break;
	  case DIR_RIGHT:
		if (d->edge < mon.rcWork.right) {
			d->edge = mon.rcWork.right;
		}
		break;
	}

	d->trect.top = mon.rcWork.top;
	d->trect.bottom = mon.rcWork.bottom;
	d->trect.left = mon.rcWork.left;
	d->trect.right = mon.rcWork.right;

	GetDelta(d);

	return TRUE;
}

void MoveToCorner(HWND HWin, int pos) {
	RECT crect, trect;
	int x, y;

	GetWindowRect(HWin, &crect);
	SystemParametersInfo(SPI_GETWORKAREA, 0, &trect, 0);

	switch (pos) {
	    case ID_MOVE_TOPLEFT:
		x = trect.left;
		y = trect.top;
		break;
	    case ID_MOVE_TOPRIGHT:
		x = trect.right - (crect.right - crect.left);
		y = trect.top;
		break;
	    case ID_MOVE_BOTTOMLEFT:
		x = trect.left;
		y = trect.bottom - (crect.bottom - crect.top);
		break;
	    case ID_MOVE_BOTTOMRIGHT:
		x = trect.right - (crect.right - crect.left);
		y = trect.bottom - (crect.bottom - crect.top);
		break;
	}

	SetWindowPos(HWin, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}

void MovePosition(HWND HWin, int dir) {
	HWND wnd;
	int num;
	GetDeltaParam dp;

	dp.delta = 0;
	dp.dir = dir;
	dp.edge = 0;
	GetWindowRect(HWin, &dp.crect);

	if (pvar->MultiMonitorSupported) {
		EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&dp);
	}
	else {
		SystemParametersInfo(SPI_GETWORKAREA, 0, &dp.trect, 0);
		GetDelta(&dp);
		switch (dir & (~DIR_ROOTONLY)) {
		  case DIR_UP:
			if (dp.edge > dp.trect.top) {
				dp.edge = dp.trect.top;
			}
			break;
		  case DIR_DOWN:
			if (dp.edge < dp.trect.bottom) {
				dp.edge = dp.trect.bottom;
			}
			break;
		  case DIR_LEFT:
			if (dp.edge > dp.trect.left) {
				dp.edge = dp.trect.left;
			}
			break;
		  case DIR_RIGHT:
			if (dp.edge < dp.trect.right) {
				dp.edge = dp.trect.right;
			}
			break;
		}
	}

	if (! (dir & DIR_ROOTONLY)) {
		for (num=0; num < MAXNWIN; num++) {
			if ((wnd = GetNthWin(num)) == NULL) {
				break;
			}
			if (wnd == HWin || IsIconic(wnd)) {
				continue;
			}
			GetWindowRect(wnd, &dp.trect);
			GetDelta(&dp);
		}
	}

	if (dir & DIR_INCREASE) {
		if (dp.dir & DIR_HORIZONTAL) {
			if (dp.crect.left + dp.delta >= dp.edge) {
				dp.delta = 0;
			}
		}
		else {
			if (dp.crect.top + dp.delta >= dp.edge) {
				dp.delta = 0;
			}
		}
	}
	else {
		dp.delta *= -1;
		if (dp.dir & DIR_HORIZONTAL) {
			if (dp.crect.right + dp.delta <= dp.edge) {
				dp.delta = 0;
			}
		}
		else {
			if (dp.crect.bottom + dp.delta <= dp.edge) {
				dp.delta = 0;
			}
		}
	}

	if (dp.delta) {
		if (dp.dir & DIR_HORIZONTAL) {
			SetWindowPos(HWin, NULL, dp.crect.left + dp.delta, dp.crect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
		}
		else {
			SetWindowPos(HWin, NULL, dp.crect.left, dp.crect.top + dp.delta, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
		}
	}
}

static int PASCAL FAR TTXProcessCommand(HWND hWin, WORD cmd) {
	switch (cmd) {
	    case ID_MOVE_UP:
		MovePosition(hWin, DIR_UP);
		return 1;
	    case ID_MOVE_DOWN:
		MovePosition(hWin, DIR_DOWN);
		return 1;
	    case ID_MOVE_LEFT:
		MovePosition(hWin, DIR_LEFT);
		return 1;
	    case ID_MOVE_RIGHT:
		MovePosition(hWin, DIR_RIGHT);
		return 1;
	    case ID_MOVE_TOP:
		MovePosition(hWin, DIR_UP | DIR_ROOTONLY);
		return 1;
	    case ID_MOVE_BOTTOM:
		MovePosition(hWin, DIR_DOWN | DIR_ROOTONLY);
		return 1;
	    case ID_MOVE_MLEFT:
		MovePosition(hWin, DIR_LEFT | DIR_ROOTONLY);
		return 1;
	    case ID_MOVE_MRIGHT:
		MovePosition(hWin, DIR_RIGHT | DIR_ROOTONLY);
		return 1;
	    case ID_MOVE_TOPLEFT:
	    case ID_MOVE_TOPRIGHT:
	    case ID_MOVE_BOTTOMLEFT:
	    case ID_MOVE_BOTTOMRIGHT:
	    	MoveToCorner(hWin, cmd);
		return 1;
	    default:
		return 0;
	}
	return 0;
}

static TTXExports Exports = {
  sizeof(TTXExports),
  ORDER,

  TTXInit,
  NULL, // TTXGetUIHooks,
  NULL, // TTXGetSetupHooks,
  NULL, // TTXOpenTCP,
  NULL, // TTXCloseTCP,
  NULL, // TTXSetWinSize,
  NULL, // TTXModifyMenu,
  NULL, // TTXModifyPopupMenu,
  TTXProcessCommand,
  NULL, // TTXEnd
};

BOOL __declspec(dllexport) PASCAL FAR TTXBind(WORD Version, TTXExports FAR * exports) {
  int size = sizeof(Exports) - sizeof(exports->size);

  if (size > exports->size) {
    size = exports->size;
  }
  memcpy((char FAR *)exports + sizeof(exports->size),
         (char FAR *)&Exports + sizeof(exports->size),
         size);
  return TRUE;
}

BOOL WINAPI DllMain(HANDLE hInstance, ULONG ul_reason, LPVOID lpReserved)
{
  switch (ul_reason) {
    case DLL_THREAD_ATTACH:
      /* do thread initialization */
      break;
    case DLL_THREAD_DETACH:
      /* do thread cleanup */
      break;
    case DLL_PROCESS_ATTACH:
      /* do process initialization */
      DoCover_IsDebuggerPresent();
      hInst = hInstance;
      pvar = &InstVar;
      break;
    case DLL_PROCESS_DETACH:
      /* do process cleanup */
      break;
  }
  return TRUE;
}