// Commands.cpp: implementation of the CCommands class
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Commands.h"
#include "xkeymacsdll.h"
#include "Utils.h"
#include
#include
#pragma data_seg(".xkmcs")
DWORD CCommands::m_nNumericArgument = 1;
BOOL CCommands::m_bSetMark = FALSE;
BOOL CCommands::m_bC_ = FALSE;
BOOL CCommands::m_bC_x = FALSE;
BOOL CCommands::m_bM_ = FALSE;
BOOL CCommands::m_bDefaultNumericArgument = TRUE;
BOOL CCommands::m_bNegativeNumericArgument = FALSE;
BOOL CCommands::m_bC_u = FALSE;
SEARCH_DIRECTION CCommands::m_SearchDirection = NA;
int (*CCommands::m_LastKillCommand)() = NULL;
int (*CCommands::m_LastCommand)() = NULL;
CPtrList CCommands::m_CaretPos;
CPtrList CCommands::m_ScrollInfo;
CPtrList CCommands::m_FindText;
BOOL CCommands::m_bFirstFindDialog = FALSE;
BOOL CCommands::m_bTemporarilyDisableXKeymacs = FALSE;
CArray CCommands::m_oClipboardData;
OriginalWindowPosition_t CCommands::m_OriginalWindowPosition[MAX_WINDOW] = {'\0'};
BOOL CCommands::m_bIsSu = FALSE;
#pragma data_seg()
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCommands::CCommands()
{
}
CCommands::~CCommands()
{
}
void CCommands::DepressKey(BYTE bVk)
{
CXkeymacsDll::DepressKey(bVk);
}
void CCommands::ReleaseKey(BYTE bVk)
{
CXkeymacsDll::ReleaseKey(bVk);
}
void CCommands::Kdu(BYTE bVk1, BYTE bVk2, BYTE bVk3, BYTE bVk4)
{
BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
if (bIsCtrlDown) {
CUtils::UpdateKeyboardState(VK_CONTROL, 0);
ReleaseKey(VK_CONTROL);
}
if (bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (bVk1) {
CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);
}
if (bVk2) {
CXkeymacsDll::Kdu(bVk2, m_nNumericArgument);
}
if (bVk3) {
CXkeymacsDll::Kdu(bVk3, m_nNumericArgument);
}
if (bVk4) {
CXkeymacsDll::Kdu(bVk4, m_nNumericArgument);
}
if (bIsAltDown) {
DepressKey(VK_MENU);
}
if (bIsCtrlDown) {
DepressKey(VK_CONTROL);
CUtils::UpdateKeyboardState(VK_CONTROL, 1);
}
}
void CCommands::SdKduSu(BYTE bVk1, BYTE bVk2, BYTE bVk3, BYTE bVk4)
{
BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
if (bIsCtrlDown) {
ReleaseKey(VK_CONTROL);
}
if (bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (!bIsShiftDown) {
DepressKey(VK_SHIFT);
}
CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);
if (bVk2) {
CXkeymacsDll::Kdu(bVk2, m_nNumericArgument);
}
if (bVk3) {
CXkeymacsDll::Kdu(bVk3, m_nNumericArgument);
}
if (bVk4) {
CXkeymacsDll::Kdu(bVk4, m_nNumericArgument);
}
if (!bIsShiftDown) {
if (CUtils::IsShuriken()) {
m_bIsSu = TRUE;
} else {
ReleaseKey(VK_SHIFT);
}
}
if (bIsAltDown) {
DepressKey(VK_MENU);
}
if (bIsCtrlDown) {
DepressKey(VK_CONTROL);
}
}
void CCommands::Su()
{
if (m_bIsSu) {
ReleaseKey(VK_SHIFT);
m_bIsSu = FALSE;
}
}
void CCommands::CdKduCu(BYTE bVk1, BYTE bVk2)
{
BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
if (!bIsCtrlDown) {
DepressKey(VK_CONTROL);
CUtils::UpdateKeyboardState(VK_CONTROL, 1);
}
if (bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (bIsShiftDown && !m_bSetMark) {
ReleaseKey(VK_SHIFT);
}
if (bVk1) {
CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);
}
if (bVk2) {
CXkeymacsDll::Kdu(bVk2, m_nNumericArgument);
}
if (bIsShiftDown && !m_bSetMark) {
if (!CUtils::IsXPorLater()) { // FIXME Windows XP said VK_SHIFT was pressed physically after a user press VK_RSHIFT, so...
DepressKey(VK_SHIFT);
}
}
if (bIsAltDown) {
DepressKey(VK_MENU);
}
if (!bIsCtrlDown) {
CUtils::UpdateKeyboardState(VK_CONTROL, 0);
ReleaseKey(VK_CONTROL);
}
}
void CCommands::CdSdKduSuCu(BYTE bVk)
{
BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
if (!bIsCtrlDown) {
DepressKey(VK_CONTROL);
CUtils::UpdateKeyboardState(VK_CONTROL, 1);
}
if (bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (!bIsShiftDown) {
DepressKey(VK_SHIFT);
}
CXkeymacsDll::Kdu(bVk, m_nNumericArgument);
if (!bIsShiftDown) {
ReleaseKey(VK_SHIFT);
}
if (bIsAltDown) {
DepressKey(VK_MENU);
}
if (!bIsCtrlDown) {
CUtils::UpdateKeyboardState(VK_CONTROL, 0);
ReleaseKey(VK_CONTROL);
}
}
void CCommands::AdKduAu(BYTE bVk1, BYTE bVk2, BYTE bVk3)
{
BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
if (bIsCtrlDown) {
ReleaseKey(VK_CONTROL);
}
if (!bIsAltDown) {
DepressKey(VK_MENU);
}
if (bIsShiftDown) {
ReleaseKey(VK_SHIFT);
}
CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);
if (bVk2) {
CXkeymacsDll::Kdu(bVk2, m_nNumericArgument);
}
if (bVk3) {
CXkeymacsDll::Kdu(bVk3, m_nNumericArgument);
}
if (bIsShiftDown) {
if (!CUtils::IsXPorLater()) { // FIXME Windows XP said VK_SHIFT was pressed physically after a user press VK_RSHIFT, so...
DepressKey(VK_SHIFT);
}
}
if (!bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (bIsCtrlDown) {
DepressKey(VK_CONTROL);
}
}
void CCommands::AdSdKduSuAu(BYTE bVk1)
{
BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
if (bIsCtrlDown) {
ReleaseKey(VK_CONTROL);
}
if (!bIsAltDown) {
DepressKey(VK_MENU);
}
if (!bIsShiftDown) {
DepressKey(VK_SHIFT);
}
CXkeymacsDll::Kdu(bVk1, m_nNumericArgument);
if (!bIsShiftDown) {
ReleaseKey(VK_SHIFT);
}
if (!bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (bIsCtrlDown) {
DepressKey(VK_CONTROL);
}
}
// C-a: Home
int CCommands::BeginningOfLine()
{
int nNumericArgument = 1;
if (!m_bDefaultNumericArgument || m_bNegativeNumericArgument) {
nNumericArgument = m_nNumericArgument;
if (m_bNegativeNumericArgument) {
if (nNumericArgument) {
nNumericArgument *= -1;
} else {
nNumericArgument = -1;
}
}
}
ClearNumericArgument();
if (nNumericArgument <= 0) {
nNumericArgument = -1 * nNumericArgument + 1;
while (nNumericArgument--) {
ReleaseKey(VK_CONTROL); // why?
while (MoveCaret(VK_UP) != GOTO_HOOK);
}
ReleaseKey(VK_CONTROL); // why?
while (MoveCaret(VK_HOME) != GOTO_HOOK);
DepressKey(VK_CONTROL); // why?
} else if (nNumericArgument == 1) {
return Reset(MoveCaret(VK_HOME));
} else if (2 <= nNumericArgument) {
nNumericArgument -= 2;
while (nNumericArgument--) {
ReleaseKey(VK_CONTROL); // why?
while (MoveCaret(VK_DOWN) != GOTO_HOOK);
}
ReleaseKey(VK_CONTROL); // why?
while (MoveCaret(VK_END) != GOTO_HOOK);
while (MoveCaret(VK_RIGHT) != GOTO_HOOK);
DepressKey(VK_CONTROL); // why?
} else {
ASSERT(0);
}
return Reset(GOTO_HOOK);
}
// C-b: Left
int CCommands::BackwardChar()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return ForwardChar();
}
return Reset(MoveCaret(VK_LEFT));
}
// M-b: backward-word
int CCommands::BackwardWord()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return ForwardWord();
}
return Reset(MoveCaret(VK_LEFT, TRUE));
}
// C-e: End
int CCommands::EndOfLine()
{
int nNumericArgument = 1;
if (!m_bDefaultNumericArgument || m_bNegativeNumericArgument) {
nNumericArgument = m_nNumericArgument;
if (m_bNegativeNumericArgument) {
if (nNumericArgument) {
nNumericArgument *= -1;
} else {
nNumericArgument = -1;
}
}
}
ClearNumericArgument();
if (nNumericArgument <= 0) {
nNumericArgument *= -1;
while (nNumericArgument--) {
ReleaseKey(VK_CONTROL); // why?
while (MoveCaret(VK_UP) != GOTO_HOOK);
}
ReleaseKey(VK_CONTROL); // why?
while (MoveCaret(VK_HOME) != GOTO_HOOK);
while (MoveCaret(VK_LEFT) != GOTO_HOOK);
DepressKey(VK_CONTROL); // why?
} else if (nNumericArgument == 1) {
return (MoveCaret(VK_END));
} else if (2 <= nNumericArgument) {
--nNumericArgument;
while (nNumericArgument--) {
ReleaseKey(VK_CONTROL); // why?
while (MoveCaret(VK_DOWN) != GOTO_HOOK);
}
ReleaseKey(VK_CONTROL); // why?
while (MoveCaret(VK_END) != GOTO_HOOK);
DepressKey(VK_CONTROL); // why?
} else {
ASSERT(0);
}
return Reset(GOTO_HOOK);
}
// C-f: Right
int CCommands::ForwardChar()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return BackwardChar();
}
return Reset(MoveCaret(VK_RIGHT));
}
// M-f: forward-word
int CCommands::ForwardWord()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return BackwardWord();
}
return Reset(MoveCaret(VK_RIGHT, TRUE));
}
// C-n: Down
int CCommands::NextLine()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return PreviousLine();
}
return Reset(MoveCaret(VK_DOWN));
}
// C-o: open-line
int CCommands::OpenLine()
{
// Kdu(VK_RETURN, VK_LEFT);
int n = m_nNumericArgument;
ClearNumericArgument();
while (n--) {
Kdu(VK_RETURN, VK_UP, VK_END);
}
return Reset(GOTO_HOOK);
}
// C-p: Up
int CCommands::PreviousLine()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return NextLine();
}
return Reset(MoveCaret(VK_UP));
}
// M-%
int CCommands::QueryReplace()
{
ClearNumericArgument();
if (CUtils::IsBecky()) {
CdKduCu('Q', 'A');
} else if (CUtils::IsEclipse()
|| CUtils::IsInternetExplorer()
|| CUtils::IsLotusNotes()
|| CUtils::IsSleipnir()) {
CdKduCu('F');
} else if (CUtils::IsAutla()
|| CUtils::IsBorlandCppBuilder()
|| CUtils::IseMemoPad()
|| CUtils::IsNami2000()
|| CUtils::IsStoryEditor()) {
CdKduCu('R');
} else if (CUtils::IsEdLeaf()) {
AdKduAu('E', 'E');
} else if (CUtils::IsPHPEditor()) {
AdKduAu('S', 'F');
} else {
CdKduCu('H');
}
return Reset(GOTO_HOOK);
}
// C-M-%
int CCommands::QueryReplaceRegexp()
{
return QueryReplace();
}
// M-<:
int CCommands::BeginningOfBuffer()
{
ClearNumericArgument();
return Reset(MoveCaret(VK_HOME, TRUE));
}
// M->:
int CCommands::EndOfBuffer()
{
ClearNumericArgument();
return Reset(MoveCaret(VK_END, TRUE));
}
// C-h: Back space
int CCommands::DeleteBackwardChar()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return DeleteChar();
}
Kdu(VK_BACK);
m_bSetMark = FALSE;
return Reset(GOTO_HOOK);
}
// C-d: Delete
int CCommands::DeleteChar()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return DeleteBackwardChar();
}
m_bSetMark = FALSE;
Kdu(VK_DELETE);
return Reset(GOTO_HOOK);
}
int CCommands::KillLineForAllFormat()
{
return KillLine(TRUE, KillLineForAllFormat);
}
// C-k: Shift-End, Shift-Delete, if the cursor is not at EOL (is End Of Line)
// Shift-Right, Cut, if the cursor is at EOL
int CCommands::KillLine()
{
return KillLine(FALSE);
}
int CCommands::KillLine(BOOL bAllFormat, int (*pCommand)())
{
static BOOL bKeepAllFormat = FALSE;
// Do not try to do these command at once.
// Clipboard has old data till you go out this function.
static int nStep = 0;
static CString szClipboardText;
static BOOL bContinuous = FALSE;
static BOOL bTopOfFile = FALSE;
switch (nStep) {
case 0: // Clear Selection and get next character to confirm the cursor is at the EOF or not.
// CUtils::Log("C-k: 0");
bTopOfFile = FALSE;
if (!m_bDefaultNumericArgument || m_bNegativeNumericArgument) {
if (m_bNegativeNumericArgument || m_nNumericArgument == 0) {
// Shift+Up x -n Shift+Home Ctrl+X
SdKduSu(VK_UP);
ClearNumericArgument();
SdKduSu(VK_HOME);
} else {
// Shift+Down x (n - 1) Shift+End Shift+Right Ctrl+X
--m_nNumericArgument;
SdKduSu(VK_DOWN);
ClearNumericArgument();
SdKduSu(VK_END, VK_RIGHT);
}
CdKduCu('X');
nStep = 6;
return Reset(GOTO_RECURSIVE);
}
if (m_LastCommand == pCommand) {
bContinuous = TRUE;
} else {
bContinuous = FALSE;
if (m_bSetMark) {
m_bSetMark = FALSE;
DeactivateMark();
}
}
if (CUtils::IsDirector()
|| CUtils::IsEudora()) {
nStep = 1;
return Reset(GOTO_RECURSIVE);
}
if (CUtils::IsLotus123()) {
// C-k: Shift-End, Control-x
SdKduSu(VK_END);
CdKduCu('X');
return Reset(GOTO_HOOK);
}
CaptureClipboardData(0, CUtils::IsLotusNotes());
if (!CopyNextCharacter()) {
// CUtils::Log("Error: CopyNextCharacter");
return Reset(GOTO_DO_NOTHING);
}
nStep = 4;
return Reset(GOTO_RECURSIVE);
case 1: // Get back character to confirm the cursor is at the TOF or not only for Macromedia Director.
// CUtils::Log("C-k: 1");
nStep = 0;
CaptureClipboardData();
if (!CopyBackCharacter()) {
return Reset(GOTO_DO_NOTHING);
}
nStep = 2;
return Reset(GOTO_RECURSIVE);
case 2: // Confirm the cursor is at the TOF or not only for Macromedia Director.
{
// CUtils::Log("C-k: 2");
nStep = 0;
Su();
if (CUtils::IsTOF()) {
bTopOfFile = TRUE;
}
// CopyBackCharacter move cursor right
Kdu(VK_LEFT);
RestoreClipboardData();
nStep = 3;
return Reset(GOTO_RECURSIVE);
}
case 3: // Get next character to confirm the cursor is at the EOF or not.
// CUtils::Log("C-k: 3");
nStep = 0;
if (CUtils::IsLotus123()) {
// C-k: Shift-End, Control-x
SdKduSu(VK_END);
CdKduCu('X');
return Reset(GOTO_HOOK);
}
CaptureClipboardData();
if (!CopyNextCharacter()) {
// CUtils::Log("Error: CopyNextCharacter");
return Reset(GOTO_DO_NOTHING);
}
nStep = 4;
return Reset(GOTO_RECURSIVE);
case 4: // Cut line
// CUtils::Log("C-k: 4");
nStep = 0;
Su();
if ((CUtils::IsDirector()
|| CUtils::IsEudora())
&& !bTopOfFile) {
// CopyNextCharacter move cursor left
Kdu(VK_RIGHT);
}
CUtils::GetClipboardText(&szClipboardText);
// CUtils::Log("%x, %s", szClipboardText.GetAt(0), szClipboardText);
if (szClipboardText.IsEmpty()) { // EOF
// CUtils::Log("C-k: EOF");
if (CUtils::IsLotusWordPro()
|| CUtils::IsMicrosoftFrontPage()
|| CUtils::IsMicrosoftWord()) {
SdKduSu(VK_RIGHT);
Cut_();
nStep = 5;
return Reset(GOTO_RECURSIVE);
} else if (CUtils::IsLotusNotes()) {
Kdu(VK_END);
ReleaseKey(VK_CONTROL); // Why is it needed?
SdKduSu(VK_DOWN, VK_HOME);
Copy_();
DepressKey(VK_CONTROL); // Why is it needed?
nStep = 5;
return Reset(GOTO_RECURSIVE);
} else {
// default
Kdu(VK_RIGHT);
RestoreClipboardData();
// CUtils::Log("C-k: 4-1");
return Reset(GOTO_HOOK);
}
}
if (szClipboardText.GetAt(0) != VK_RETURN) {
// CUtils::Log("C-k: szClipboardText.GetAt(0) != VK_RETURN");
if (CUtils::IsDirector()) {
ReleaseKey(VK_CONTROL);
SdKduSu(VK_END);
Copy_();
DepressKey(VK_CONTROL);
} else if (CUtils::IseMemoPad()
|| CUtils::IsHidemaru() // Hidemaru clears mark after copy.
|| CUtils::IsOpenOffice()
|| CUtils::IsTuruKameMail()) {
SdKduSu(VK_END);
Cut_();
} else if (CUtils::IsLotusWordPro()
|| CUtils::IsMicrosoftWord()) {
SdKduSu(VK_END, VK_LEFT);
Cut_();
} else {
SdKduSu(VK_END);
Copy_();
}
} else { // EOL
// CUtils::Log("C-k: EOL");
if (CUtils::IsDirector()) {
ReleaseKey(VK_CONTROL);
SdKduSu(VK_RIGHT);
Copy_();
DepressKey(VK_CONTROL);
} else if (CUtils::IsEclipse()
|| CUtils::IsStoryEditor()) {
SdKduSu(VK_RIGHT);
Copy_();
} else if (CUtils::IseMemoPad()
|| CUtils::IsHidemaru() // Hidemaru clears mark after copy.
|| CUtils::IsOpenOffice()
|| CUtils::IsTuruKameMail()) {
SdKduSu(VK_RIGHT);
Cut_();
} else {
SdKduSu(VK_RIGHT);
Copy_();
}
}
nStep = 5;
return Reset(GOTO_RECURSIVE);
case 5: // input return if XKeymacs not only line but also line feed code and set the kill-line data on the clipboard.
// CUtils::Log("C-k: 5");
nStep = 0;
Su();
CaptureClipboardData(1, CUtils::IsLotusNotes());
if (CUtils::IseMemoPad()
|| CUtils::IsHidemaru() // Hidemaru clears mark after copy.
|| CUtils::IsLotusWordPro()
|| CUtils::IsMicrosoftWord ()
|| CUtils::IsOpenOffice()
|| CUtils::IsTuruKameMail()) {
// do nothing
} else {
if (0 < FindReturnFromClipboardData(1)) {
SdKduSu(VK_LEFT);
Copy_();
nStep = 5;
return Reset(GOTO_RECURSIVE);
} else {
Kdu(VK_DELETE);
}
}
bKeepAllFormat = bAllFormat;
if (!bKeepAllFormat
&& !m_oClipboardData[1]->IsAllMergeableFormat()) {
bKeepAllFormat = TRUE;
}
if (bContinuous && !bKeepAllFormat) {
*m_oClipboardData[0] += *m_oClipboardData[1];
} else {
*m_oClipboardData[0] = *m_oClipboardData[1];
}
RestoreClipboardData(0);
nStep = 6;
return Reset(GOTO_RECURSIVE);
case 6: // add data into kill-ring
// CUtils::Log("C-k: 6");
nStep = 0;
Su();
if (bContinuous && bKeepAllFormat) {
CXkeymacsDll::AddKillRing(FALSE);
} else {
CXkeymacsDll::AddKillRing();
}
return Reset(GOTO_HOOK);
break;
}
return Reset(GOTO_HOOK);
}
// C-x u: C-/: C-_: Ctrl-Z
int CCommands::Undo()
{
if (CUtils::IsMicrosoftWord()) {
static BOOL bIsCtrlDown;
static BOOL bIsAltDown;
static BOOL bIsShiftDown;
bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
if (!bIsCtrlDown) {
DepressKey(VK_CONTROL);
}
if (bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (bIsShiftDown) {
ReleaseKey(VK_SHIFT);
}
PostMessage(GetFocus(), WM_KEYDOWN, 'Z', 0);
if (bIsShiftDown) {
DepressKey(VK_SHIFT);
}
if (bIsAltDown) {
DepressKey(VK_MENU);
}
if (!bIsCtrlDown) {
ReleaseKey(VK_CONTROL);
}
} else {
CdKduCu('Z');
}
return Reset(GOTO_HOOK);
}
// C-x C-c: Alt-Space, Alt-C
int CCommands::SaveBuffersKillEmacs()
{
ClearNumericArgument();
HWND hWnd = GetForegroundWindow();
if (hWnd) {
OriginalWindowPosition_t *pOriginalWindowPosition = GetOriginalWindowPosition(hWnd);
if (pOriginalWindowPosition && pOriginalWindowPosition->bMax[ROLL_UP_UNROLL]) {
RollUpUnroll();
}
}
if (CUtils::IsConsole()) {
SystemMenu(CMD_CLOSE);
} else if (CUtils::IsExplorer()) {
ReleaseKey(VK_CONTROL);
AdKduAu(VK_F4);
} else if (CUtils::IsInternetExplorer()
|| CUtils::IsJavaW()) {
AdKduAu(VK_F4);
} else {
AdKduAu(VK_SPACE, 'C');
}
return Reset(GOTO_HOOK);
}
// C-z: Alt-Space, Alt-N
int CCommands::IconifyOrDeiconifyFrame()
{
ClearNumericArgument();
if (CUtils::IsConsole()) {
SystemMenu(CMD_MINIMIZE);
} else {
AdKduAu(VK_SPACE, 'N');
}
return Reset(GOTO_HOOK);
}
int CCommands::Restore()
{
ClearNumericArgument();
if (CUtils::IsConsole()) {
SystemMenu(CMD_RESTORE);
} else {
AdKduAu(VK_SPACE, 'R');
}
return Reset(GOTO_HOOK);
}
int CCommands::Move()
{
ClearNumericArgument();
if (CUtils::IsConsole()) {
SystemMenu(CMD_MOVE);
} else {
AdKduAu(VK_SPACE, 'M');
}
return Reset(GOTO_HOOK);
}
int CCommands::Size()
{
ClearNumericArgument();
if (CUtils::IsConsole()) {
SystemMenu(CMD_SIZE);
} else {
AdKduAu(VK_SPACE, 'S');
}
return Reset(GOTO_HOOK);
}
int CCommands::Minimize()
{
return IconifyOrDeiconifyFrame();
}
int CCommands::Maximize()
{
ClearNumericArgument();
HWND hWnd = GetForegroundWindow();
if (!hWnd) {
return Reset(GOTO_HOOK);
}
WINDOWPLACEMENT wndpl = {sizeof(WINDOWPLACEMENT)};
if (!GetWindowPlacement(hWnd, &wndpl)) {
return Reset(GOTO_HOOK);
}
if (wndpl.showCmd == SW_SHOWMAXIMIZED) {
wndpl.showCmd = SW_RESTORE;
} else {
wndpl.showCmd = SW_SHOWMAXIMIZED;
}
SetWindowPlacement(hWnd, &wndpl);
return Reset(GOTO_HOOK);
}
OriginalWindowPosition_t* CCommands::GetOriginalWindowPosition(HWND hWnd)
{
const int nOriginalWindowPosition = sizeof(m_OriginalWindowPosition) / sizeof(m_OriginalWindowPosition[0]);
for (int i = 0; i < nOriginalWindowPosition; ++i) {
if (m_OriginalWindowPosition[i].hWnd == hWnd) {
return &m_OriginalWindowPosition[i];
}
}
for (int j = 0; j < nOriginalWindowPosition; ++j) {
if (m_OriginalWindowPosition[j].hWnd == 0) {
m_OriginalWindowPosition[j].hWnd = hWnd;
memset(&m_OriginalWindowPosition[(j + 1) % nOriginalWindowPosition], 0, sizeof(m_OriginalWindowPosition[0]));
return &m_OriginalWindowPosition[j];
}
}
ASSERT(0);
return NULL;
}
int CCommands::Maximize(MAXIMIZE_DIRECTION direction)
{
ClearNumericArgument();
HWND hWnd = GetForegroundWindow();
if (!hWnd) {
return Reset(GOTO_HOOK);
}
RECT workarea = {'\0'};
if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea, 0)) {
return Reset(GOTO_HOOK);
}
RECT window = {'\0'};
if (!GetWindowRect(hWnd, &window)) {
return Reset(GOTO_HOOK);
}
OriginalWindowPosition_t *pOriginalWindowPosition = GetOriginalWindowPosition(hWnd);
if (!pOriginalWindowPosition) {
return Reset(GOTO_HOOK);
}
int X = window.left;
int Y = window.top;
int nWidth = window.right - window.left;
int nHeight = window.bottom - window.top;
switch (direction) {
case VERTICAL:
if (pOriginalWindowPosition->bMax[direction]) {
Y = pOriginalWindowPosition->nOriginalY;
nHeight = pOriginalWindowPosition->nOriginalHeight;
} else {
pOriginalWindowPosition->nOriginalY = Y;
pOriginalWindowPosition->nOriginalHeight = nHeight;
Y = workarea.top;
nHeight = workarea.bottom - workarea.top;
}
break;
case HORIZONTAL:
if (pOriginalWindowPosition->bMax[direction]) {
X = pOriginalWindowPosition->nOriginalX;
nWidth = pOriginalWindowPosition->nOriginalWidth;
} else {
pOriginalWindowPosition->nOriginalX = X;
pOriginalWindowPosition->nOriginalWidth = nWidth;
X = workarea.left;
nWidth = workarea.right - workarea.left;
}
break;
case ROLL_UP_UNROLL:
if (pOriginalWindowPosition->bMax[direction]) {
nHeight = pOriginalWindowPosition->nOriginalHeight;
} else {
pOriginalWindowPosition->nOriginalHeight = nHeight;
nHeight = 0x15;
}
break;
default:
ASSERT(0);
break;
}
MoveWindow(hWnd, X, Y, nWidth, nHeight, TRUE);
pOriginalWindowPosition->bMax[direction] = !pOriginalWindowPosition->bMax[direction];
return Reset(GOTO_HOOK);
}
int CCommands::MaximizeVertically()
{
return Maximize(VERTICAL);
}
int CCommands::MaximizeHorizontally()
{
return Maximize(HORIZONTAL);
}
// C-Space:
int CCommands::SetMarkCommand()
{
ClearNumericArgument();
if (m_bSetMark) {
DeactivateMark();
}
m_bSetMark = TRUE;
if (CUtils::IsConsole()) {
SystemMenuEdit(CMD_MARK);
}
return Reset(GOTO_HOOK);
}
// C-g: Keyboard quit
int CCommands::KeyboardQuit()
{
ClearNumericArgument();
if (CUtils::IsFindDialog()) {
Kdu(VK_ESCAPE);
}
if (m_bSetMark) {
m_bSetMark = FALSE;
DeactivateMark();
}
SetTemporarilyDisableXKeymacs(FALSE);
return Reset(GOTO_HOOK);
}
DWORD CCommands::ClickCaret()
{
HWND hWnd = GetFocus();
POINT CaretPos = {'\0'};
if (!GetCaretPos(&CaretPos)) {
return GetLastError();
}
// CUtils::Log("client: x = %d, y = %d", CaretPos.x, CaretPos.y);
if (!ClientToScreen(hWnd, &CaretPos)) {
return GetLastError();
}
// CUtils::Log("screen: x = %d, y = %d", CaretPos.x, CaretPos.y);
POINT Delta = {0, 1};
if (CUtils::IsSakuraEditor()) {
Delta.x = 1;
Delta.y = 29; // OK: 29-42 NG: 28, 43
}
const POINT clickPoint = {CaretPos.x + Delta.x, CaretPos.y + Delta.y};
return Click(&clickPoint);
}
DWORD CCommands::DeactivateMark()
{
if (CUtils::IsOpenOffice()
|| CUtils::IsVisualBasicEditor()) {
// GetCaretPos always returen (x,y) = (0,0) on OpenOffice, so ...
// GetCaretPos always returen (x,y) = (-2199,*) on M$ Excel VBE, so ...
Kdu(VK_ESCAPE);
return ERROR_SUCCESS; // i.e. return 0;
}
if (CUtils::IsFlash()
|| CUtils::IsInternetExplorer()
|| CUtils::IsMicrosoftPowerPoint()
|| CUtils::IsMicrosoftWord()
|| CUtils::IsSleipnir()
|| CUtils::IsThunderbird()) {
// GetCaretPos always returen (x,y) = (0,0) on M$ Word and Thunderbird, so ...
// GetCaretPos always returen start point on IE (and Sleipnir that uses IE), so ...
Kdu(VK_RIGHT);
return ERROR_SUCCESS; // i.e. return 0;
}
if (CUtils::IsDirector()) {
// GetCaretPos always returen (x,y) = (0,0) on Macromedia Director, so ...
Kdu(VK_RIGHT, VK_LEFT);
return ERROR_SUCCESS; // i.e. return 0;
}
if (CUtils::IsExplorer()) {
AdKduAu('E', 'A');
AdKduAu('E', 'I');
return ERROR_SUCCESS; // i.e. return 0;
}
return ClickCaret();
}
// C-x C-f: Alt-F, Alt-O
int CCommands::FindFile()
{
ClearNumericArgument();
if (CUtils::IsFlash()
|| CUtils::IsSleipnir()) {
CdKduCu('O');
} else if (CUtils::IsVisualStudioDotNet()) {
AdKduAu('F', 'O', 'F');
} else {
AdKduAu('F', 'O');
}
return Reset(GOTO_HOOK);
}
// C-i: Tab
int CCommands::TabToTabStop()
{
ClearNumericArgument();
if (m_bSetMark) {
m_bSetMark = FALSE;
}
Kdu(VK_TAB);
return Reset(GOTO_HOOK);
}
// C-m: Enter
int CCommands::Newline()
{
Kdu(VK_RETURN);
return Reset(GOTO_HOOK);
}
// C-x h: Ctrl-End, Ctrl-Shift-Home
int CCommands::MarkWholeBuffer()
{
ClearNumericArgument();
if (CUtils::IsConsole()) {
SystemMenuEdit(CMD_SELECT_ALL);
} else if (CUtils::IsDreamweaver()
|| CUtils::IsFireworks()
|| CUtils::IsFlash()
|| CUtils::IsIllustrator()
|| CUtils::IsPaint()
|| CUtils::IsPhotoshop()) {
CdKduCu('A');
} else if (CUtils::IsExplorer()
|| CUtils::IsReget()) {
Kdu(VK_END);
m_bSetMark = TRUE;
return Reset(MoveCaret(VK_HOME));
} else {
CdKduCu(VK_END);
m_bSetMark = TRUE;
return Reset(MoveCaret(VK_HOME, TRUE));
}
return Reset(GOTO_HOOK);
}
// C-x C-p:
int CCommands::MarkPage()
{
return MarkWholeBuffer();
}
// C-x C-s: Alt-F, Alt-S
int CCommands::SaveBuffer()
{
ClearNumericArgument();
if (CUtils::IsFlash()
|| CUtils::IsSleipnir()) {
CdKduCu('S');
return Reset(GOTO_HOOK);
} else {
// default
AdKduAu('F', 'S');
return Reset(GOTO_HOOK);
}
}
// C-v: Page Down
int CCommands::ScrollUp()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return ScrollDown();
}
if (m_bDefaultNumericArgument) {
return Reset(MoveCaret(VK_NEXT));
} else {
while (m_nNumericArgument--) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEDOWN, NULL);
}
}
return Reset(GOTO_HOOK);
}
// M-v: Page Up
int CCommands::ScrollDown()
{
if (m_bNegativeNumericArgument) {
m_bNegativeNumericArgument = FALSE;
return ScrollUp();
}
if (m_bDefaultNumericArgument) {
if (CUtils::IsFirefox()
|| CUtils::IsVisualCpp()) {
CdKduCu(0); // dummy to clear Alt effect.
}
return Reset(MoveCaret(VK_PRIOR));
} else {
while (m_nNumericArgument--) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEUP, NULL);
}
}
return Reset(GOTO_HOOK);
}
BOOL CCommands::bC_()
{
return m_bC_;
}
void CCommands::bC_(BOOL b)
{
m_bC_ = b;
CXkeymacsDll::ModifyShell_NotifyIcon(CTRL_ICON, m_bC_);
}
BOOL CCommands::bC_x()
{
return m_bC_x;
}
void CCommands::bC_x(BOOL b)
{
m_bC_x = b;
CXkeymacsDll::ModifyShell_NotifyIcon(CX_ICON, m_bC_x);
}
// C-x: only set flag
int CCommands::C_x()
{
if (CXkeymacsDll::GetEnableCUA() && m_bSetMark) {
Cut();
} else {
bC_x(TRUE);
}
return Reset(GOTO_HOOKX);
}
// C-x C-w: Alt-F, Alt-A
int CCommands::WriteFile()
{
ClearNumericArgument();
if (CUtils::IsSleipnir()) {
CdKduCu('S');
} else if (CUtils::IsFlash()) {
CdSdKduSuCu('S');
} else {
AdKduAu('F', 'A');
}
return Reset(GOTO_HOOK);
}
int CCommands::Paste()
{
ClearNumericArgument();
m_bSetMark = FALSE;
if (CUtils::IsConsole()) {
SystemMenuEdit(CMD_PASTE);
} else {
CdKduCu('V');
}
return Reset(GOTO_HOOK);
}
// C-w: Ctrl-X
int CCommands::KillRegion()
{
static int nStep = 0;
switch (nStep) {
case 0:
m_bSetMark = FALSE;
ClearNumericArgument();
CdKduCu('X');
if (CUtils::IsExplorer()) {
return Reset(GOTO_HOOK);
}
nStep = 1;
return Reset(GOTO_RECURSIVE);
case 1:
nStep = 0;
CXkeymacsDll::AddKillRing();
return Reset(GOTO_HOOK);
}
// dummy
return Reset(GOTO_HOOK);
}
// M-w: Ctrl-C
int CCommands::KillRingSave()
{
static int nStep = 0;
switch (nStep) {
case 0:
ClearNumericArgument();
m_bSetMark = FALSE;
if (CUtils::IsConsole()) {
SystemMenuEdit(CMD_COPY);
return Reset(GOTO_HOOK);
} else if (CUtils::IsMicrosoftPowerPoint()) { // PowerPoint did not want to deactivate-mark. Temporary code?
CdKduCu('X');
} else {
CdKduCu('C');
}
if (CUtils::IsExplorer()) {
return Reset(GOTO_HOOK);
}
nStep = 1;
return Reset(GOTO_RECURSIVE);
case 1:
nStep = 0;
CXkeymacsDll::AddKillRing();
if (CUtils::IsMicrosoftPowerPoint()) { // Because DeactivateMark move object like graph.
CdKduCu('V');
} else {
DeactivateMark();
}
return Reset(GOTO_HOOK);
}
// dummy
return Reset(GOTO_HOOK);
}
// C-y: Ctrl-V
int CCommands::Yank()
{
m_bSetMark = FALSE;
if (CUtils::IsConsole()) {
SystemMenuEdit(CMD_PASTE);
} else {
static CClipboardSnap* pSnap = NULL;
if (!m_bDefaultNumericArgument) {
DecreaseNumericArgument();
CXkeymacsDll::IncreaseKillRingIndex(m_nNumericArgument);
pSnap = CXkeymacsDll::GetKillRing(pSnap);
} else if (pSnap) {
pSnap = CXkeymacsDll::GetKillRing(pSnap);
} else {
if (CUtils::IsExcel() && m_LastKillCommand == KillRegion) {
// do nothing to work C-w not Copy but Cut
} else if (CUtils::IsLotusNotes() && (m_LastKillCommand == KillRegion || m_LastKillCommand == KillRingSave)) {
// do nothing
} else {
pSnap = CXkeymacsDll::GetKillRing(pSnap, FALSE);
}
}
CdKduCu('V');
if (pSnap) {
return Reset(GOTO_RECURSIVE);
}
}
return Reset(GOTO_HOOK);
}
// M-y: yank-pop
int CCommands::YankPop()
{
ClearNumericArgument();
if (m_LastCommand == YankPop
|| m_LastCommand == Yank) {
static CClipboardSnap* pSnap = NULL;
if (!pSnap) {
CClipboardSnap* pOldSnap = NULL;
pOldSnap = CXkeymacsDll::GetKillRing(pOldSnap);
if (pOldSnap) {
for (int i = 0; i < pOldSnap->GetCount(); ++i) {
CdKduCu('Z');
}
} else {
CdKduCu('Z');
}
CXkeymacsDll::IncreaseKillRingIndex();
}
pSnap = CXkeymacsDll::GetKillRing(pSnap);
CdKduCu('V');
if (pSnap) {
return Reset(GOTO_RECURSIVE);
}
}
return Reset(GOTO_HOOK);
}
// M-!: cmd.exe/command.com
int CCommands::ShellCommand()
{
if (!CUtils::Run(getenv("XKEYMACS_SHELL"))) {
CUtils::Run(getenv("COMSPEC"));
}
return Reset(GOTO_HOOK);
}
int CCommands::Ignore()
{
Reset(); // If you delete this line, Ignore() works as Enable/Disable XKeymacs only on Release build. Why?
return Reset(GOTO_HOOK);
}
void CCommands::bM_(BOOL b)
{
m_bM_ = b;
CXkeymacsDll::ModifyShell_NotifyIcon(META_ICON, m_bM_);
}
BOOL CCommands::bM_()
{
return m_bM_;
}
// C-[
int CCommands::Meta()
{
bM_(TRUE);
return Reset(GOTO_HOOKX);
}
// Esc
int CCommands::MetaEscape()
{
Meta();
return Reset(GOTO_DO_NOTHING);
}
// Alt
int CCommands::MetaAlt()
{
return Reset(GOTO_DO_NOTHING);
}
// C-0
int CCommands::NumericArgument0()
{
return NumericArgument(0);
}
// C-1
int CCommands::NumericArgument1()
{
return NumericArgument(1);
}
// C-2
int CCommands::NumericArgument2()
{
return NumericArgument(2);
}
// C-3
int CCommands::NumericArgument3()
{
return NumericArgument(3);
}
// C-4
int CCommands::NumericArgument4()
{
return NumericArgument(4);
}
// C-5
int CCommands::NumericArgument5()
{
return NumericArgument(5);
}
// C-6
int CCommands::NumericArgument6()
{
return NumericArgument(6);
}
// C-7
int CCommands::NumericArgument7()
{
return NumericArgument(7);
}
// C-8
int CCommands::NumericArgument8()
{
return NumericArgument(8);
}
// C-9
int CCommands::NumericArgument9()
{
return NumericArgument(9);
}
// C-#
int CCommands::NumericArgument(int n)
{
if (m_bDefaultNumericArgument) {
m_nNumericArgument = n;
m_bDefaultNumericArgument = FALSE;
} else {
m_nNumericArgument = m_nNumericArgument * 10 + n;
}
return Reset(GOTO_HOOK0_9);
}
// C--, M--
int CCommands::NumericArgumentMinus()
{
m_bNegativeNumericArgument = !m_bNegativeNumericArgument;
return Reset(GOTO_HOOK0_9);
}
// C-u
int CCommands::UniversalArgument()
{
if (m_bC_u) {
m_nNumericArgument *= 4;
} else {
m_nNumericArgument = 4;
m_bC_u = TRUE;
}
return Reset(GOTO_HOOKX);
}
// change function name and member variable name like bUniversalArgument()
BOOL CCommands::bC_u()
{
return m_bC_u;
}
void CCommands::bC_u(BOOL b)
{
m_bC_u = b;
}
int CCommands::Repeat(BYTE bVk)
{
if (m_bDefaultNumericArgument) {
return Reset(GOTO_DO_NOTHING);
} else {
CXkeymacsDll::Kdu(bVk, m_nNumericArgument);
return Reset(GOTO_HOOK);
}
}
// C-l: Recenter
int CCommands::Recenter()
{
if (CUtils::IsBecky()) {
static int nStep = 0;
RECT ClientRect;
GetClientRect(GetFocus(), &ClientRect);
static int gap = INT_MAX;
static POINT CaretPos;
GetCaretPos(&CaretPos);
switch (nStep) {
case 0:
nStep = 0; // omaginai
if (CaretPos.y < ClientRect.bottom / 2) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEUP, NULL);
} else if (ClientRect.bottom / 2 < CaretPos.y) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEDOWN, NULL);
} else {
gap = INT_MAX;
return Reset(GOTO_HOOK);
break;
}
Kdu(VK_DOWN);
nStep = 1;
return Reset(GOTO_RECURSIVE);
case 1:
nStep = 0;
// When a client screen can display 2n lines, the center line is (n + 1)th line.
int newgap = CaretPos.y - ClientRect.bottom / 2;
if (fabs((double)gap) <= fabs((double)newgap)) {
if ((fabs((double)gap) == fabs((double)newgap)) && (gap != newgap) && newgap < 0) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEUP, NULL);
}
gap = INT_MAX;
return Reset(GOTO_HOOK);
break;
}
gap = newgap;
return Reset(GOTO_RECURSIVE);
}
} else {
RECT ClientRect;
GetClientRect(GetFocus(), &ClientRect);
int gap = INT_MAX;
for (;;) {
POINT CaretPos;
GetCaretPos(&CaretPos);
if (CaretPos.y < ClientRect.bottom / 2) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEUP, NULL);
} else if (ClientRect.bottom / 2 < CaretPos.y) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEDOWN, NULL);
} else {
break;
}
// When a client screen can display 2n lines, the center line is (n + 1)th line.
int newgap = CaretPos.y - ClientRect.bottom / 2;
if (fabs((double)gap) <= fabs((double)newgap)) {
if ((fabs((double)gap) == fabs((double)newgap)) && (gap != newgap) && newgap < 0) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEUP, NULL);
}
break;
}
gap = newgap;
}
return Reset(GOTO_HOOK);
}
return Reset(GOTO_HOOK);
}
// C-t: Shift-Left, Shift-Delete, Right Shift-Insert, if the cursor is not at EOL (is End Of Line)
// Left, Shift-Right, Shift-Delete, Left, Shift-Insert, Right, if the cursor is at EOL
int CCommands::TransposeChars()
{
ClearNumericArgument(); // tmp
// Do not try to do these command at once.
// Clipboard has old data till you go out this function.
static int nStep = 0;
switch (nStep) {
case 0: // Clear Selection
if (m_bSetMark) {
m_bSetMark = FALSE;
Kdu(VK_RIGHT, VK_LEFT);
nStep = 1;
return Reset(GOTO_RECURSIVE);
} else {
// Do nothing. Go to case 1:
}
case 1: // Get back character to confirm the cursor is at TOF or not.
nStep = 0;
CaptureClipboardData();
// simple version
if (CUtils::IsLotus123()) {
// C-t: Left, Shift-Right, Shift-Delete, Left, Shift-Insert, Right
Kdu(VK_LEFT);
SdKduSu(VK_RIGHT, VK_DELETE);
Kdu(VK_LEFT);
SdKduSu(VK_INSERT);
Kdu(VK_RIGHT);
nStep = 7;
return Reset(GOTO_RECURSIVE);
}
if (!CopyBackCharacter()) {
return Reset(GOTO_DO_NOTHING);
}
nStep = 2;
return Reset(GOTO_RECURSIVE);
case 2: // Get next character to confirm the cursor is at the EOF or not.
{
nStep = 0;
Su();
if (CUtils::IsTOF()) {
Kdu(VK_LEFT);
nStep = 7;
return Reset(GOTO_RECURSIVE);
}
if (CUtils::IsDirector()) {
// CopyBackCharacter move cursor right
Kdu(VK_LEFT);
ReleaseKey(VK_CONTROL);
}
if (CUtils::IsEudora()) {
// CopyBackCharacter move cursor right
Kdu(VK_LEFT);
}
if (!CopyNextCharacter()) {
nStep = 7;
return Reset(GOTO_RECURSIVE);
}
if (CUtils::IsDirector()) {
DepressKey(VK_CONTROL);
}
nStep = 3;
return Reset(GOTO_RECURSIVE);
}
case 3: // Cut Left Character
{
nStep = 0;
Su();
CString szClipboardText;
CUtils::GetClipboardText(&szClipboardText);
// CUtils::Log("%x, %d, %s", szClipboardText.GetAt(0), szClipboardText.GetLength(), szClipboardText);
if (CUtils::IsDirector()
|| CUtils::IsEudora()) {
// CopyNextCharacter move cursor left
Kdu(VK_RIGHT);
}
if (!szClipboardText.IsEmpty()
&& szClipboardText.GetAt(0) != VK_RETURN) {
if (CUtils::IseMemoPad()
|| CUtils::IsFlash()
|| CUtils::IsK2Editor()
|| CUtils::IsShuriken()) {
SdKduSu(VK_LEFT);
CdKduCu('X');
} else if (CUtils::IsDirector()) {
ReleaseKey(VK_CONTROL);
SdKduSu(VK_LEFT);
CdKduCu('X');
Kdu(VK_RIGHT);
DepressKey(VK_CONTROL);
} else {
SdKduSu(VK_LEFT, VK_DELETE);
}
nStep = 4;
return Reset(GOTO_RECURSIVE);
} else {
if (szClipboardText.IsEmpty()) { // EOF
if (CUtils::IsLotusNotes()
|| CUtils::IsLotusWordPro()
|| CUtils::IsMicrosoftFrontPage()
|| CUtils::IsMicrosoftWord()) {
// These applications say "EOL is EOF".
Kdu(VK_END);
} else {
// default
Kdu(VK_RIGHT);
}
}
nStep = 5;
return Reset(GOTO_RECURSIVE);
}
nStep = 7;
return Reset(GOTO_RECURSIVE);
}
case 4: // Paste the cut character
nStep = 0;
Su();
Kdu(VK_RIGHT);
if (CUtils::IsDirector()
|| CUtils::IseMemoPad()
|| CUtils::IsFlash()
|| CUtils::IsK2Editor()
|| CUtils::IsShuriken()) {
CdKduCu('V');
} else {
SdKduSu(VK_INSERT);
}
nStep = 7;
return Reset(GOTO_RECURSIVE);
case 5: // Cut character at the EOF.
nStep = 0;
if (CUtils::IsDirector()
|| CUtils::IseMemoPad()
|| CUtils::IsFlash()
|| CUtils::IsK2Editor()
|| CUtils::IsShuriken()) {
SdKduSu(VK_LEFT);
CdKduCu('X');
} else {
SdKduSu(VK_LEFT, VK_DELETE);
}
nStep = 6;
return Reset(GOTO_RECURSIVE);
case 6: // Paste the cut character near the EOF.
nStep = 0;
Su();
Kdu(VK_LEFT);
if (CUtils::IsDirector()
|| CUtils::IseMemoPad()
|| CUtils::IsFlash()
|| CUtils::IsK2Editor()
|| CUtils::IsShuriken()) {
DepressKey(VK_CONTROL); // Why is this code needed?
CdKduCu('V');
} else {
SdKduSu(VK_INSERT);
}
Kdu(VK_RIGHT);
nStep = 7;
return Reset(GOTO_RECURSIVE);
case 7: // Set the original data on the clipboard.
nStep = 0;
Su();
RestoreClipboardData();
return Reset(GOTO_HOOK);
}
return Reset(GOTO_HOOK);
}
void CCommands::Cut_()
{
CdKduCu('X');
}
int CCommands::Cut()
{
ClearNumericArgument();
m_bSetMark = FALSE;
Cut_();
return Reset(GOTO_HOOK);
}
void CCommands::Copy_()
{
if (CUtils::IsConsole()) {
SystemMenuEdit(CMD_COPY);
} else if (CUtils::IsEclipse()
|| CUtils::IsStoryEditor()) {
CdKduCu(VK_INSERT);
} else {
CdKduCu('C');
}
}
int CCommands::Copy()
{
ClearNumericArgument();
m_bSetMark = FALSE;
Copy_();
return Reset(GOTO_HOOK);
}
// Copy next character of the cursor if the caret is NOT at end of the file
// Move the caret to left if caret is at end of the file
BOOL CCommands::CopyNextCharacter()
{
if (!CUtils::OpenClipboard()) {
ASSERT(0);
return FALSE;
}
if (!EmptyClipboard()) {
ASSERT(0);
return FALSE;
}
if (!CloseClipboard()) {
ASSERT(0);
return FALSE;
}
SdKduSu(VK_RIGHT);
Copy_();
Kdu(VK_LEFT);
return TRUE;
}
BOOL CCommands::CopyBackCharacter()
{
if (!CUtils::OpenClipboard()) {
ASSERT(0);
return FALSE;
}
if (!EmptyClipboard()) {
ASSERT(0);
return FALSE;
}
if (!CloseClipboard()) {
ASSERT(0);
return FALSE;
}
SdKduSu(VK_LEFT);
Copy_();
Kdu(VK_RIGHT);
return TRUE;
}
void CCommands::DecreaseNumericArgument()
{
if (m_bNegativeNumericArgument) {
++m_nNumericArgument;
} else {
if (m_nNumericArgument == 0) {
++m_nNumericArgument;
m_bNegativeNumericArgument = TRUE;
} else {
--m_nNumericArgument;
}
}
}
void CCommands::ClearNumericArgument()
{
m_bDefaultNumericArgument = TRUE;
m_nNumericArgument = 1;
m_bNegativeNumericArgument = FALSE;
}
void CCommands::Reset()
{
Reset(GOTO_HOOK);
}
int CCommands::Reset(int rc)
{
switch(rc) {
case GOTO_HOOK:
ClearNumericArgument();
m_bC_u = FALSE;
case GOTO_HOOK0_9:
bC_(FALSE);
bC_x(FALSE);
bM_(FALSE);
case GOTO_HOOKX:
break;
case GOTO_RECURSIVE:
break;
case GOTO_DO_NOTHING:
break;
default:
break;
}
return rc;
}
// C-q
int CCommands::EnableOrDisableXKeymacs()
{
// dummy
ASSERT(0);
static int i = 0; // If there is not this 2 line, EnableOrDisableXKeymacs, EnableXKeymacs and DisableXKeymacs has same function pointer.
++i;
return Reset(GOTO_HOOK);
}
int CCommands::EnableXKeymacs()
{
// dummy
ASSERT(0);
static int i = 0;
++i;
return Reset(GOTO_HOOK);
}
int CCommands::DisableXKeymacs()
{
// dummy
ASSERT(0);
static int i = 0;
++i;
return Reset(GOTO_HOOK);
}
int CCommands::GetNumericArgument()
{
return m_nNumericArgument;
}
// C-r
int CCommands::IsearchBackward()
{
return Search(BACKWARD);
}
// C-s
int CCommands::IsearchForward()
{
return Search(FORWARD);
}
void CCommands::OpenFindDialog()
{
if (CUtils::IsAutla()
|| CUtils::IsBorlandCppBuilder()
|| CUtils::IsCodeWarrior()
|| CUtils::IsDana()
|| CUtils::IseMemoPad()
|| CUtils::IsJmEditor()
|| CUtils::IsK2Editor()
|| (CUtils::IsNotepad() && CUtils::IsNTor9x())
|| CUtils::IsOedit()
|| CUtils::IsOpenJane()
|| CUtils::IsPHPEditor()
|| CUtils::IsStoryEditor()
|| CUtils::IsTeraPad()) {
AdKduAu('S', 'F');
} else if (CUtils::IsConsole()) {
SystemMenuEdit(CMD_FIND);
} else if (CUtils::IsSakuraEditor()) {
AdKduAu('S', VK_RETURN);
} else if (CUtils::IsNami2000()) {
AdKduAu('D', 'F');
} else if (CUtils::IsVisualStudioDotNet()) {
AdKduAu('E', 'F', 'F');
} else if (CUtils::IsDirector()) {
AdKduAu('E', 'F', 'T');
} else if (CUtils::IsAdobeReader()) {
AdKduAu('E', 'S');
} else if (CUtils::IsDWFM()
|| CUtils::IsEggExplorer()
|| CUtils::IsExplorer()
|| CUtils::IsOutlookExpress()) {
Kdu(VK_F3);
} else if (CUtils::IsHidemaru()
|| CUtils::IsMicrosoftPowerPoint()
|| CUtils::IsMozilla()
|| CUtils::IsNetscape()
|| CUtils::IsOpera()
|| CUtils::IsSleipnir()) {
CdKduCu('F');
} else if (CUtils::IsDreamweaver()
|| CUtils::IsezHTML()
|| CUtils::IsFlash()) {
DepressKey(VK_CONTROL); // Why is this coad needed?
CdKduCu('F');
} else if (CUtils::IsIPMessenger()) {
DepressKey(VK_CONTROL);
PostMessage(GetFocus(), WM_KEYDOWN, 'F', 0);
PostMessage(GetFocus(), WM_KEYUP, 'F', 0);
ReleaseKey(VK_CONTROL);
} else {
// default
AdKduAu('E', 'F');
}
// Set Direction if Find dialog already exist
if (CUtils::IsDWFM()
|| CUtils::IsEggExplorer()
|| CUtils::IsExplorer()
|| CUtils::IsFirefox()
|| CUtils::IsHidemaru()
|| CUtils::IsK2Editor()
|| CUtils::IsLotusWordPro()
|| CUtils::IsMicrosoftPowerPoint()
|| CUtils::IsMozilla()
|| CUtils::IsMSDN()
|| CUtils::IsNetscape()
|| CUtils::IsOpera()
|| CUtils::IsSakuraEditor()) {
} else if (CUtils::IsInternetExplorer()
|| CUtils::IsSleipnir()) {
// I want to set direction but IE does not allow me.
} else {
SetSearchDirection();
}
}
int CCommands::Search(SEARCH_DIRECTION direction)
{
// CUtils::Log("%s", CUtils::GetApplicationName());
if (CUtils::IsIllustrator()
|| CUtils::IsPaint()
|| CUtils::IsPhotoshop()) {
return Reset(GOTO_DO_NOTHING);
}
ClearNumericArgument();
if ((direction != FORWARD) && (direction != BACKWARD)) {
ASSERT(0);
}
if (!CUtils::IsFindDialog()) {
// CUtils::Log("Find Dialog is not.");
// F3 or Shift+F3
if (m_LastCommand == IsearchForward
|| m_LastCommand == IsearchBackward) {
if (CUtils::IsBecky()
|| CUtils::IsFirefox()
|| CUtils::IsHidemaru()
|| CUtils::IsPHPEditor()) {
if (m_LastCommand == IsearchForward && direction != FORWARD
|| m_LastCommand == IsearchBackward && direction != BACKWARD) {
// do nothing
} else if (direction == FORWARD) {
Kdu(VK_F3);
} else if (direction == BACKWARD) {
SdKduSu(VK_F3);
}
return Reset(GOTO_HOOK);
} else if (CUtils::IsBorlandCppBuilder()) {
if (m_LastCommand == IsearchForward && direction != FORWARD
|| m_LastCommand == IsearchBackward && direction != BACKWARD) {
AdKduAu('S', 'F');
SetSearchDirection(direction);
Kdu(VK_RETURN);
} else {
Kdu(VK_F3);
}
return Reset(GOTO_HOOK);
}
}
m_SearchDirection = direction;
OpenFindDialog();
} else {
// CUtils::Log("Find Dialog is opened.");
if (CUtils::IsHidemaru()
|| CUtils::IsK2Editor()
|| CUtils::IsOedit()
|| CUtils::IsSakuraEditor()) {
BYTE bDirection = 0;
if (direction == FORWARD) {
bDirection = GetDirectionForwardKey();
} else if (direction == BACKWARD) {
bDirection = GetDirectionBackwardKey();
} else {
ASSERT(0);
}
AdKduAu(bDirection);
} else if (CUtils::IsBorlandCppBuilder()) {
if (m_SearchDirection != direction) {
SetSearchDirection(direction);
} else {
Kdu(VK_RETURN);
}
} else if (CUtils::IsJmEditor()
|| CUtils::IsPHPEditor()) {
Kdu(VK_RETURN);
} else if (CUtils::IsAutla()) {
if (direction == FORWARD) {
Kdu(VK_F3);
} else if (direction == BACKWARD) {
SdKduSu(VK_F3);
} else {
ASSERT(0);
}
} else {
if (m_SearchDirection != direction) {
// Set Direction if Find dialog already exist
if (CUtils::IsConsole()) {
SetSearchDirection(BACKWARD); // bad style
m_SearchDirection = direction;
} else {
SetSearchDirection(direction);
}
return Reset(GOTO_HOOK);
}
// "Find Next(F)" if Find dialog already exist
if (CUtils::IsStoryEditor()) {
AdKduAu('F');
} else {
Kdu(VK_RETURN);
}
// open Find dialog again
CString szDialogTitle;
CUtils::GetFindDialogTitle(&szDialogTitle);
if (CUtils::IsNami2000()) {
AdKduAu('D', 'F');
SetSearchDirection();
} else if (CUtils::IsOutlook()
&& szDialogTitle.Compare("検索")) {
// Outlook (w/o Japanese version)
AdKduAu('E', 'F');
} else if (CUtils::IsVisualCpp()) {
CdKduCu('F');
DepressKey(VK_CONTROL); // Why is this need???
} else if (CUtils::IsCodeWarrior()
|| CUtils::IsDana()
|| CUtils::IsStoryEditor()
|| CUtils::IsTeraPad()) {
AdKduAu('S', 'F');
} else if (CUtils::IsezHTML()) {
CdKduCu('F');
}
// set cursor at end of FindWhat
if (CUtils::IsMozilla()
|| CUtils::IsNetscape()) {
// do nothing
} else if (CUtils::IsMicrosoftWord()) {
CUtils::UpdateKeyboardState(VK_CONTROL, 0);
ReleaseKey(VK_CONTROL);
AdKduAu('N');
Kdu(VK_ESCAPE);
Kdu(VK_END);
DepressKey(VK_CONTROL);
CUtils::UpdateKeyboardState(VK_CONTROL, 1);
} else {
AdKduAu(GetFindWhatKey());
}
Kdu(VK_END);
}
}
return Reset(GOTO_HOOK);
}
void CCommands::SetSearchDirection(SEARCH_DIRECTION direction)
{
// CUtils::Log("SetSearchDirection: %d", direction);
if ((direction != FORWARD) && (direction != BACKWARD)) {
return;
}
m_SearchDirection = direction;
if (GetDirectionForwardKey() == 0 && GetDirectionBackwardKey() == 0) {
Kdu(VK_END);
return;
} else if (CUtils::IsConsole()) {
if (direction == BACKWARD) { // bad style
Kdu(VK_TAB, VK_TAB);
Kdu(VK_RIGHT);
SdKduSu(VK_TAB, VK_TAB);
}
} else if (CUtils::IsMicrosoftWord()) {
CUtils::UpdateKeyboardState(VK_CONTROL, 0);
ReleaseKey(VK_CONTROL);
AdKduAu('M');
AdKduAu(0xBA); // VK_OEM_1 Used for miscellaneous characters; it can vary by keyboard.
// Windows 2000/XP: For the US standard keyboard, the ';:' key
Kdu(VK_UP, VK_UP);
if (direction == BACKWARD) {
Kdu(VK_DOWN);
}
AdKduAu('N');
Kdu(VK_ESCAPE);
Kdu(VK_END);
DepressKey(VK_CONTROL);
CUtils::UpdateKeyboardState(VK_CONTROL, 1);
} else if (CUtils::IsLotusNotes()) {
BYTE bDirection = 0;
if (direction == FORWARD) {
bDirection = GetDirectionForwardKey();
} else if (direction == BACKWARD) {
bDirection = GetDirectionBackwardKey();
}
AdKduAu(GetSearchOptionKey(), bDirection, GetSearchOptionKey());
{
CString szDialogTitle;
CUtils::GetFindDialogTitle(&szDialogTitle);
if (!szDialogTitle.Compare("検索")
|| !szDialogTitle.Compare("Find")) {
SdKduSu(VK_TAB);
} else {
SdKduSu(VK_TAB, VK_TAB);
}
}
Kdu(VK_END);
} else if (CUtils::IsBecky()) {
AdKduAu(GetDirectionForwardKey());
if (direction == BACKWARD) {
Kdu(VK_UP);
}
Kdu(VK_TAB, VK_TAB, VK_TAB, VK_TAB);
Kdu(VK_END);
} else if (CUtils::IsMozilla()
|| CUtils::IsNetscape()) {
Kdu(VK_TAB, VK_TAB, VK_TAB, VK_SPACE);
SdKduSu(VK_TAB, VK_TAB, VK_TAB);
} else if (CUtils::IsezHTML()) {
BYTE bDirection = 0;
if (direction == FORWARD) {
bDirection = GetDirectionForwardKey();
} else if (direction == BACKWARD) {
bDirection = GetDirectionBackwardKey();
}
AdKduAu(bDirection);
SdKduSu(VK_TAB, VK_TAB, VK_TAB, VK_TAB);
} else {
// default
BYTE bDirection = 0;
if (direction == FORWARD) {
bDirection = GetDirectionForwardKey();
} else if (direction == BACKWARD) {
bDirection = GetDirectionBackwardKey();
}
// CUtils::Log("aSetSearchDirection: Direction = %c, FindWhatKey = %c", bDirection, GetFindWhatKey());
AdKduAu(bDirection, GetFindWhatKey());
}
}
// C-x C-j, C-o, C-\, C-BACKSLASH
int CCommands::ToggleInputMethod()
{
SetInputMethodOpenStatus(TOGGLE_INPUT_METHOD);
return Reset(GOTO_HOOK);
}
int CCommands::CompleteToggleInputMethod()
{
SetInputMethodOpenStatus(TOGGLE_INPUT_METHOD, TRUE);
return Reset(GOTO_HOOK);
}
int CCommands::OpenInputMethod()
{
SetInputMethodOpenStatus(OPEN_INPUT_METHOD);
return Reset(GOTO_HOOK);
}
int CCommands::CloseInputMethod()
{
SetInputMethodOpenStatus(CLOSE_INPUT_METHOD);
return Reset(GOTO_HOOK);
}
int CCommands::CompleteCloseInputMethod()
{
SetInputMethodOpenStatus(CLOSE_INPUT_METHOD, TRUE);
return Reset(GOTO_HOOK);
}
void CCommands::SetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status, BOOL isComplete)
{
ClearNumericArgument();
HKL hKL = GetKeyboardLayout(0);
if (CUtils::IsConsole()) {
Kdu(VK_KANJI);
} else if (ImmIsIME(hKL)) {
// default
HWND hWnd = GetFocus();
HIMC hIMC = ImmGetContext(hWnd);
if (isComplete && ImmGetOpenStatus(hIMC)) {
ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
}
switch (status) {
case CLOSE_INPUT_METHOD:
ImmSetOpenStatus(hIMC, FALSE);
break;
case OPEN_INPUT_METHOD:
ImmSetOpenStatus(hIMC, TRUE);
break;
case TOGGLE_INPUT_METHOD:
ImmSetOpenStatus(hIMC, !ImmGetOpenStatus(hIMC));
break;
default:
ASSERT(0);
break;
}
ImmReleaseContext(hWnd, hIMC);
} else {
Kdu(VK_KANJI);
}
}
// C-x k: Ctrl+F4
int CCommands::KillBuffer()
{
CdKduCu(VK_F4);
return Reset(GOTO_HOOK);
}
BOOL CCommands::IsKillCommand(int (*nFunctionPointer)())
{
for (int nCommandID = 1; nCommandID < sizeof(Commands) / sizeof(Commands[0]); ++nCommandID) {
if (Commands[nCommandID].fCommand == nFunctionPointer) {
return !strncmp(Commands[nCommandID].szCommandName, "kill-", 5);
}
}
return FALSE;
}
void CCommands::SetLastCommand(int (__cdecl *LastCommand)(void))
{
m_LastCommand = LastCommand;
if (IsKillCommand(LastCommand)) {
m_LastKillCommand = LastCommand;
}
}
// M-d:
int CCommands::KillWord()
{
static int nStep = 0;
static CString szClipboardText;
static int nWhiteSpace = 0;
switch (nStep) {
case 0:
ClearNumericArgument();
szClipboardText.Empty();
nWhiteSpace = 0;
CdSdKduSuCu(VK_RIGHT);
CdKduCu('X');
nStep = 1;
return Reset(GOTO_RECURSIVE);
case 1:
{
nStep = 0;
CUtils::GetClipboardText(&szClipboardText);
int nWordEnd = szClipboardText.GetLength();
int nFirstSpace = szClipboardText.Find(' ');
if (nFirstSpace == 0) {
nStep = 0;
return Reset(GOTO_RECURSIVE);
} else if (0 < nFirstSpace) {
nWordEnd = nFirstSpace; // (nFirstSpace + 1) - 1
}
int nFirstTab = szClipboardText.Find('\t');
if (nFirstTab == 0) {
nStep = 0;
return Reset(GOTO_RECURSIVE);
} else if (0 < nFirstTab && nFirstTab < nWordEnd) {
nWordEnd = nFirstTab; // (nFirstTab + 1) - 1
}
if (nWordEnd == szClipboardText.GetLength()) {
nStep = 4;
} else {
CString szEndWhiteSpace;
nWhiteSpace = szClipboardText.GetLength() - nWordEnd;
szEndWhiteSpace = szClipboardText.Right(nWhiteSpace);
CUtils::SetClipboardText(&szEndWhiteSpace);
szClipboardText = szClipboardText.Left(nWordEnd);
nStep = 2;
}
return Reset(GOTO_RECURSIVE);
}
case 2:
nStep = 0;
CdKduCu('V');
nStep = 3;
return Reset(GOTO_RECURSIVE);
case 3:
nStep = 0;
m_bDefaultNumericArgument = FALSE;
m_nNumericArgument = nWhiteSpace;
Kdu(VK_LEFT);
nStep = 4;
return Reset(GOTO_RECURSIVE);
case 4:
nStep = 0;
CUtils::SetClipboardText(&szClipboardText);
nStep = 5;
return Reset(GOTO_RECURSIVE);
case 5:
nStep = 0;
CXkeymacsDll::AddKillRing();
m_bSetMark = FALSE;
return Reset(GOTO_HOOK);
}
// dummy
return Reset(GOTO_HOOK);
}
// M-DEL
int CCommands::BackwardKillWord()
{
CdSdKduSuCu(VK_LEFT);
Cut_();
return Reset(GOTO_HOOK);
}
// Select All
int CCommands::SelectAll()
{
if (CUtils::IsConsole()) {
SystemMenuEdit(CMD_SELECT_ALL);
} else {
CdKduCu('A');
}
return Reset(GOTO_HOOK);
}
// C-x (
int CCommands::StartKbdMacro()
{
if (CUtils::IsMicrosoftWord()) {
AdKduAu('T', 'M', 'R');
} else if (CUtils::IsHidemaru()) {
SdKduSu(VK_F1);
} else {
CXkeymacsDll::DefiningMacro(TRUE);
}
return Reset(GOTO_HOOK);
}
// C-x )
int CCommands::EndKbdMacro()
{
if (CUtils::IsMicrosoftWord()) {
AdKduAu('T', 'M', 'R');
} else if (CUtils::IsHidemaru()) {
SdKduSu(VK_F1);
} else {
CXkeymacsDll::DefiningMacro(FALSE);
}
return Reset(GOTO_HOOK);
}
// C-x e
int CCommands::CallLastKbdMacro()
{
if (CUtils::IsMicrosoftWord()) {
AdKduAu('T', 'M', 'M');
} else if (CUtils::IsHidemaru()) {
int n = 1;
if (!m_bDefaultNumericArgument) {
n = m_nNumericArgument;
}
ClearNumericArgument();
while (n--) {
AdKduAu('M', 'P');
}
} else {
while (m_nNumericArgument--) {
CXkeymacsDll::CallMacro();
}
}
return Reset(GOTO_HOOK);
}
int CCommands::SwitchBetweenInputLocales()
{
BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
// Alt+Shift
if (bIsCtrlDown) {
ReleaseKey(VK_CONTROL);
}
DepressKey(VK_MENU); // why?
ReleaseKey(VK_MENU);
DepressKey(VK_MENU);
DepressKey(VK_SHIFT);
ReleaseKey(VK_SHIFT);
if (!bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (bIsCtrlDown) {
DepressKey(VK_CONTROL);
}
return Reset(GOTO_HOOK);
}
// C-x b
int CCommands::SwitchToBuffer()
{
ClearNumericArgument();
// GetWindowInfo does not get information to find out if the window is MDI or SDI.
CdKduCu(VK_TAB);
return Reset(GOTO_HOOK);
}
int CCommands::C_()
{
return Reset(GOTO_HOOKX);
}
int CCommands::C_Eisu()
{
bC_(TRUE);
return Reset(GOTO_HOOKX);
}
int CCommands::Escape()
{
ClearNumericArgument();
Kdu(VK_ESCAPE);
return Reset(GOTO_HOOK);
}
int CCommands::Tilde()
{
ClearNumericArgument();
if (CXkeymacsData::Is106Keyboard()) {
SdKduSu(0xDE); // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard.
Su(); // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
} else {
SdKduSu(0xC0); // VK_OEM_3 Used for miscellaneous characters; it can vary by keyboard.
Su(); // Windows 2000/XP: For the US standard keyboard, the '`~' key
}
return Reset(GOTO_HOOK);
}
int CCommands::BackQuote()
{
ClearNumericArgument();
if (CXkeymacsData::Is106Keyboard()) {
SdKduSu(0xC0);
Su();
} else {
ReleaseKey(VK_SHIFT);
Kdu(0xC0); // VK_OEM_3 Used for miscellaneous characters; it can vary by keyboard.
// Windows 2000/XP: For the US standard keyboard, the '`~' key
}
return Reset(GOTO_HOOK);
}
BOOL CCommands::IsSetMark()
{
return m_bSetMark;
}
BYTE CCommands::GetFindWhatKey()
{
BYTE bFindWhat = 'N';
if (CUtils::IsBecky()
|| CUtils::IsDana()
|| CUtils::IsEclipse()
|| CUtils::IsezHTML()
|| CUtils::IsLotusNotes()
|| CUtils::IsVisualBasicEditor()) {
bFindWhat = 'F';
} else if (CUtils::IseMemoPad()) {
bFindWhat = 'K';
} else if (CUtils::IsHidemaru()
|| CUtils::IsJmEditor()) {
bFindWhat = 'S';
} else if (CUtils::IsBorlandCppBuilder()
|| CUtils::IsNami2000()
|| CUtils::IsStoryEditor()
|| CUtils::IsTeraPad()) {
bFindWhat = 'T';
} else if (CUtils::IsAdobeReader()
|| CUtils::IsAutla()
|| CUtils::IsCodeWarrior()
|| CUtils::IsFirefox()
|| CUtils::IsFlash()
|| CUtils::IsIPMessenger()
|| CUtils::IsK2Editor()
|| CUtils::IsOedit()
|| CUtils::IsOpera()
|| CUtils::IsOpenJane()
|| CUtils::IsPHPEditor()
|| CUtils::IsSakuraEditor()) {
bFindWhat = 0;
}
return bFindWhat;
}
BYTE CCommands::GetSearchOptionKey()
{
BYTE bSearchOption = 0;
if (CUtils::IsLotusNotes()) {
bSearchOption = 'O';
}
return bSearchOption;
}
BYTE CCommands::GetDirectionForwardKey()
{
BYTE bDirectionForward = 'D';
CString szDialogTitle;
CUtils::GetFindDialogTitle(&szDialogTitle);
if (CUtils::IsAdobeReader()
|| CUtils::IsAutla()
|| CUtils::IsCodeWarrior()
|| CUtils::IsDirector()
|| CUtils::IsDreamweaver()
|| CUtils::IsExcel()
|| CUtils::IsFirefox()
|| CUtils::IsFireworks()
|| CUtils::IsFlash()
|| CUtils::IsIPMessenger()
|| CUtils::IsJmEditor()
|| CUtils::IsLotus123()
|| CUtils::IsMicrosoftPowerPoint()
|| CUtils::IsOpera()
|| CUtils::IsOpenJane()
|| CUtils::IsStoryEditor()
|| CUtils::IsVisualBasicEditor()
|| CUtils::IsWordpad()) {
bDirectionForward = 0;
} else if (CUtils::IsLotusNotes()
|| CUtils::IsNami2000()
|| CUtils::IsSakuraEditor()) {
bDirectionForward = 'D';
} else if (CUtils::IsOedit()) {
bDirectionForward = 'F';
} else if (CUtils::IsBecky()) {
if (!szDialogTitle.Compare("本文内検索")) {
bDirectionForward = 'O';
} else {
bDirectionForward = 0;
}
} else if (CUtils::IsK2Editor()) {
bDirectionForward = 'L';
} else if (CUtils::IseMemoPad()
|| CUtils::IsHidemaru()) {
bDirectionForward = 'N';
} else if (CUtils::IsEclipse()) {
bDirectionForward = 'O';
}
if (CUtils::IsOutlook()
&& !szDialogTitle.Compare("Find")) {
// Outlook (English version)
bDirectionForward = 0;
}
return bDirectionForward;
}
BYTE CCommands::GetDirectionBackwardKey()
{
BYTE bDirectionBackward = 'U';
CString szDialogTitle;
CUtils::GetFindDialogTitle(&szDialogTitle);
if (CUtils::IsAdobeReader()
|| CUtils::IsAutla()
|| CUtils::IsCodeWarrior()
|| CUtils::IsDirector()
|| CUtils::IsDreamweaver()
|| CUtils::IsExcel()
|| CUtils::IsFirefox()
|| CUtils::IsFireworks()
|| CUtils::IsFlash()
|| CUtils::IsIPMessenger()
|| CUtils::IsJmEditor()
|| CUtils::IsLotus123()
|| CUtils::IsMicrosoftPowerPoint()
|| CUtils::IsOpera()
|| CUtils::IsOpenJane()
|| CUtils::IsStoryEditor()
|| CUtils::IsVisualBasicEditor()
|| CUtils::IsWordpad()) {
bDirectionBackward = 0;
} else if (CUtils::IsBorlandCppBuilder()
|| CUtils::IsEclipse()
|| CUtils::IseMemoPad()
|| CUtils::IsLotusNotes()
|| CUtils::IsNami2000()) {
bDirectionBackward = 'B';
} else if (CUtils::IsBecky()) {
if (!szDialogTitle.Compare("本文内検索")) {
bDirectionBackward = 'B';
} else {
bDirectionBackward = 0;
}
} else if (CUtils::IsHidemaru()
|| CUtils::IsOedit()) {
bDirectionBackward = 'P';
} else if (CUtils::IsK2Editor()
|| CUtils::IsSakuraEditor()) {
bDirectionBackward = 'U';
}
if (CUtils::IsOutlook()
&& !szDialogTitle.Compare("Find")) {
// Outlook (English version)
bDirectionBackward = 0;
}
return bDirectionBackward;
}
void CCommands::GetCaretPosition()
{
// CUtils::Log("GetClipboardTextLength = %d", CUtils::GetClipboardTextLength());
POINT *pCaretPos = new POINT;
if (GetCaretPos(pCaretPos)) {
// CUtils::Log("x = %d, y = %d", pCaretPos->x, pCaretPos->y);
m_CaretPos.AddTail(pCaretPos);
} else {
delete pCaretPos;
pCaretPos = NULL;
}
SCROLLINFO *pScrollInfo = new SCROLLINFO;
memset(pScrollInfo, 0, sizeof(SCROLLINFO));
pScrollInfo->cbSize = sizeof(SCROLLINFO);
pScrollInfo->fMask = SIF_ALL;
if (GetScrollInfo(GetFocus(), SB_VERT, pScrollInfo)) {
// CUtils::Log("page = %d, pos = %d, max = %d, min = %d, trackpos = %d", pScrollInfo->nPage, pScrollInfo->nPos, pScrollInfo->nMax, pScrollInfo->nMin, pScrollInfo->nTrackPos);
m_ScrollInfo.AddTail(pScrollInfo);
} else {
// CUtils::Log("GetScrollInfo Error: %d", GetLastError());
delete pScrollInfo;
pScrollInfo = NULL;
}
CString* pClipboardText = new CString;
CUtils::GetClipboardText(pClipboardText);
CUtils::SetClipboardText(pClipboardText);
m_FindText.AddTail(pClipboardText);
}
BOOL CCommands::SetCaretPosition()
{
{
// TCHAR buf[0x100] = {'\0'};
// GetWindowText(GetForegroundWindow(), buf, sizeof(buf));
// CUtils::Log(buf);
}
if (!m_ScrollInfo.IsEmpty()) {
SCROLLINFO* pScrollInfo = (SCROLLINFO*)m_ScrollInfo.GetTail();
delete pScrollInfo;
pScrollInfo = NULL;
m_ScrollInfo.RemoveTail();
}
if (!m_ScrollInfo.IsEmpty()) {
SCROLLINFO* pScrollInfo = (SCROLLINFO*)m_ScrollInfo.GetTail();
SendMessage(GetFocus(), WM_VSCROLL, SB_THUMBPOSITION | (pScrollInfo->nPos << 0x10), NULL);
}
BOOL bMoveCaret = FALSE;
if (!m_CaretPos.IsEmpty()) {
POINT* pCaretPos = (POINT*)m_CaretPos.GetTail();
delete pCaretPos;
pCaretPos = NULL;
m_CaretPos.RemoveTail();
}
if (!m_CaretPos.IsEmpty()) {
POINT* pCaretPos = (POINT*)m_CaretPos.GetTail();
SetCaretPos(pCaretPos->x, pCaretPos->y);
// CUtils::Log("set x = %d, y = %d", p->x, p->y);
DeactivateMark();
const int nPreviousFindTextLength = CUtils::GetClipboardTextLength();
if (0 < nPreviousFindTextLength) {
if (CUtils::IsWordpad()) {
POSITION position = m_FindText.GetTailPosition();
CString* pPreviousFindText = (CString*)m_FindText.GetPrev(position);
CString* pNextFindText = (CString*)m_FindText.GetPrev(position);
if (*pPreviousFindText == *pNextFindText) {
for (int i = 0; i <= nPreviousFindTextLength; ++i) {
Kdu(VK_LEFT);
}
} else {
Kdu(VK_LEFT);
}
}
bMoveCaret = TRUE;
}
} else {
Kdu(VK_LEFT);
}
// CUtils::Log("scrollInfo.GetCount() = %d, szFindText.GetLength() = %d", scrollInfo.GetCount(), szFindText.GetLength());
if (!m_FindText.IsEmpty()) {
CString *pFindText = (CString *)m_FindText.GetTail();
delete pFindText;
pFindText = NULL;
m_FindText.RemoveTail();
}
if (!m_FindText.IsEmpty()) {
CString *pFindText = (CString *)m_FindText.GetTail();
CUtils::SetClipboardText(pFindText);
}
return bMoveCaret;
}
void CCommands::SetMark(BOOL bSetMark)
{
m_bSetMark = bSetMark;
}
GOTO CCommands::MoveCaret(BYTE bVk, BOOL bCtrl)
{
switch (bVk) {
case VK_PRIOR:
case VK_NEXT:
case VK_END:
case VK_HOME:
case VK_LEFT:
case VK_UP:
case VK_RIGHT:
case VK_DOWN:
break;
default:
return CONTINUE;
}
if (bCtrl) {
if (m_bSetMark) {
CdSdKduSuCu(bVk);
} else {
CdKduCu(bVk);
}
} else {
if (m_bSetMark) {
if (CUtils::IsShuriken()) {
static BOOL bIsShiftDown = FALSE;
static int nStep = 0;
switch (nStep) {
case 0:
{
BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
if (bIsCtrlDown) {
ReleaseKey(VK_CONTROL);
}
if (bIsAltDown) {
ReleaseKey(VK_MENU);
}
if (!bIsShiftDown) {
DepressKey(VK_SHIFT);
}
CXkeymacsDll::Kdu(bVk, m_nNumericArgument);
if (bIsAltDown) {
DepressKey(VK_MENU);
}
if (bIsCtrlDown) {
DepressKey(VK_CONTROL);
}
nStep = 1;
return GOTO_RECURSIVE;
}
case 1:
nStep = 0;
if (!bIsShiftDown) {
ReleaseKey(VK_SHIFT);
}
return GOTO_HOOK;
}
} else {
SdKduSu(bVk);
}
} else {
Kdu(bVk);
}
}
return GOTO_HOOK;
}
int CCommands::PassThrough()
{
Reset(); // Why?
return Reset(GOTO_HOOK);
}
int CCommands::Redo()
{
if (CUtils::IsCorelDRAW()) {
CdSdKduSuCu('Z');
} else {
CdKduCu('Y');
}
return Reset(GOTO_HOOK);
}
int CCommands::TemporarilyDisableXKeymacs()
{
// CUtils::Log("SetTemporarilyDisableXKeymacs");
SetTemporarilyDisableXKeymacs(TRUE);
Reset(); // Why?
return Reset(GOTO_HOOK);
}
BOOL CCommands::IsTemporarilyDisableXKeymacs()
{
return m_bTemporarilyDisableXKeymacs;
}
void CCommands::SetTemporarilyDisableXKeymacs(BOOL bTemporarilyDisableXKeymacs)
{
m_bTemporarilyDisableXKeymacs = bTemporarilyDisableXKeymacs;
CXkeymacsDll::SetKeyboardHookFlag();
}
int CCommands::New()
{
ClearNumericArgument();
m_bSetMark = FALSE;
CdKduCu('N');
return Reset(GOTO_HOOK);
}
int CCommands::Print()
{
ClearNumericArgument();
m_bSetMark = FALSE;
CdKduCu('P');
return Reset(GOTO_HOOK);
}
int CCommands::Find()
{
ClearNumericArgument();
m_bSetMark = FALSE;
CdKduCu('F');
return Reset(GOTO_HOOK);
}
int CCommands::FindNext()
{
ClearNumericArgument();
m_bSetMark = FALSE;
Kdu(VK_F3);
return Reset(GOTO_HOOK);
}
int CCommands::SystemMenu(const CONSOLE_MENU nDown)
{
// CUtils::Log("SystemMenu");
if (!CUtils::IsConsole()) {
return ERROR_SUCCESS;
}
RECT consoleWindowRect = {'\0'};
if (!GetWindowRect(GetForegroundWindow(), &consoleWindowRect)) {
return GetLastError();
}
// CUtils::Log("t = %d, l = %d", consoleWindowRect.top, consoleWindowRect.left);
const POINT clickPoint = {consoleWindowRect.left + 5, consoleWindowRect.top + 5};
int rc = Click(&clickPoint);
if (rc != ERROR_SUCCESS) {
return rc;
}
if (nDown != CMD_EDIT) {
for (int i = 0; i <= nDown; ++i) {
Kdu(VK_DOWN);
}
Kdu(VK_UP);
Kdu(VK_RETURN);
}
return ERROR_SUCCESS; // i.e. return 0;
}
int CCommands::SystemMenuEdit(const CONSOLE_MENU_EDIT nDown)
{
if (!CUtils::IsConsole()) {
return ERROR_SUCCESS;
}
SystemMenu(CMD_EDIT);
RECT consoleWindowRect = {'\0'};
if (!GetWindowRect(GetForegroundWindow(), &consoleWindowRect)) {
return GetLastError();
}
const y = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYMENU) * 6 + 20; // y = A + B * 6 + 20
const POINT clickPoint = {consoleWindowRect.left + 50, consoleWindowRect.top + y}; // 146 <= y <= 161 on W2K (146 + 161 + 1) / 2 = 154 = 19 + 19 x 6 + 21
int rc = Click(&clickPoint); // 157 <= y <= 172 on WXP (157 + 172 + 1) / 2 = 165 = 26 + 20 x 6 + 19
if (rc != ERROR_SUCCESS) {
return rc;
}
for (int i = 0; i <= nDown; ++i) {
Kdu(VK_DOWN);
}
Kdu(VK_UP); // Why? Because Mark did not work well only one VK_DOWN (or seven VK_DOWNs).
Kdu(VK_RETURN);
return ERROR_SUCCESS; // i.e. return 0;
}
int CCommands::Click(const POINT *const pClickPoint)
{
BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
POINT CursorPos = {'\0'};
if (!GetCursorPos(&CursorPos)) {
return GetLastError();
}
if (!SetCursorPos(pClickPoint->x, pClickPoint->y)) {
return GetLastError();
}
if (CUtils::IsConsole()
&& bIsAltDown) {
ReleaseKey(VK_MENU);
}
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, GetMessageExtraInfo());
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, GetMessageExtraInfo());
if (!SetCursorPos(CursorPos.x, CursorPos.y)) {
return GetLastError();
}
return ERROR_SUCCESS;
}
// C-x C-t
int CCommands::TransposeLines()
{
static int nStep = 0;
switch (nStep) {
case 0:
nStep = 0;
// CUtils::Log("C-x C-t: 0");
Kdu(VK_END);
CaptureClipboardData();
nStep = 1;
return Reset(GOTO_RECURSIVE);
case 1:
nStep = 0;
// CUtils::Log("C-x C-t: 1");
if (!CopyNextCharacter()) {
return Reset(GOTO_DO_NOTHING);
}
nStep = 2;
return Reset(GOTO_RECURSIVE);
case 2:
nStep = 0;
// CUtils::Log("C-x C-t: 2");
Su();
if (CUtils::IsEOF()) {
Kdu(VK_END, VK_RETURN, VK_UP, VK_END);
}
Kdu(VK_HOME);
nStep = 3;
return Reset(GOTO_RECURSIVE);
case 3:
nStep = 0;
// CUtils::Log("C-x C-t: 3");
if (!CopyBackCharacter()) {
return Reset(GOTO_DO_NOTHING);
}
nStep = 4;
return Reset(GOTO_RECURSIVE);
case 4:
nStep = 0;
// CUtils::Log("C-x C-t: 4");
Su();
if (CUtils::IsTOF()) { // TOF
Kdu(VK_DOWN, VK_END);
// CUtils::Log("C-x C-t: TOF");
nStep = 5;
} else {
nStep = 7;
}
return Reset(GOTO_RECURSIVE);
case 5:
nStep = 0;
// CUtils::Log("C-x C-t: 5");
if (!CopyNextCharacter()) {
return Reset(GOTO_DO_NOTHING);
}
nStep = 6;
return Reset(GOTO_RECURSIVE);
case 6:
nStep = 0;
// CUtils::Log("C-x C-t: 6");
Su();
if (CUtils::IsEOF()) {
Kdu(VK_END, VK_RETURN, VK_UP, VK_END);
// CUtils::Log("C-x C-t: EOF2");
}
nStep = 7;
return Reset(GOTO_RECURSIVE);
case 7:
nStep = 0;
// CUtils::Log("C-x C-t: 7");
Kdu(VK_UP, VK_HOME);
SdKduSu(VK_DOWN);
CdKduCu('X');
nStep = 8;
return Reset(GOTO_RECURSIVE);
case 8:
nStep = 0;
// CUtils::Log("C-x C-t: 8");
Su();
Kdu(VK_DOWN);
CdKduCu('V');
nStep = 9;
return Reset(GOTO_RECURSIVE);
case 9:
nStep = 0;
// CUtils::Log("C-x C-t: 9");
RestoreClipboardData();
break;
}
return Reset(GOTO_HOOK);
}
void CCommands::CaptureClipboardData(const int nID, const BOOL bTextOnly)
{
{
int nSize = nID + 1;
if (m_oClipboardData.GetSize() < nSize) {
m_oClipboardData.SetSize(nSize);
}
}
if (!m_oClipboardData[nID]) {
CClipboardSnap *pSnap = new CClipboardSnap;
if (!pSnap) {
return;
}
m_oClipboardData.SetAt(nID, pSnap);
}
BOOL bCapture = m_oClipboardData[nID]->Capture(bTextOnly);
Sleep(0); // for OpenOffice
bCapture = m_oClipboardData[nID]->Capture(bTextOnly); // for "office drawing shape format". Can CClipboardSnap care this problem?
if (!bCapture) {
// CUtils::Log("Can not Capture in CaptureClipboardData");
delete m_oClipboardData[nID];
m_oClipboardData.SetAt(nID, NULL);
}
}
void CCommands::RestoreClipboardData(const int nID)
{
if (nID + 1 <= m_oClipboardData.GetSize() && m_oClipboardData[nID]) {
m_oClipboardData[nID]->Restore();
}
}
int CCommands::FindReturnFromClipboardData(const int nID)
{
if (nID + 1 <= m_oClipboardData.GetSize() && m_oClipboardData[nID]) {
return m_oClipboardData[nID]->FindReturn();
}
return -1;
}
BOOL CCommands::IsEmptyClipboardData(const int nID)
{
if (nID + 1 <= m_oClipboardData.GetSize() && m_oClipboardData[nID]) {
return m_oClipboardData[nID]->IsEmpty();
}
return FALSE;
}
void CCommands::PrintFunctionName(int (*nFunctionPointer)())
{
for (int nCommandID = 1; nCommandID < sizeof(Commands) / sizeof(Commands[0]); ++nCommandID) {
if (Commands[nCommandID].fCommand == nFunctionPointer) {
CUtils::Log("m_LastCommand: %s", Commands[nCommandID].szCommandName);
}
}
}
int CCommands::CapsLock()
{
ClearNumericArgument();
Kdu(VK_CAPITAL);
return Reset(GOTO_HOOK);
}
int CCommands::Underscore()
{
ClearNumericArgument();
if (CXkeymacsData::Is106Keyboard()) {
SdKduSu(0xE2); // VK_OEM_102 Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
Su();
} else {
SdKduSu(0xBD); // VK_OEM_MINUS Windows 2000/XP: For any country/region, the '-' key
Su();
}
return Reset(GOTO_HOOK);
}
int CCommands::RollUpUnroll()
{
return Maximize(ROLL_UP_UNROLL);
}
int CCommands::Retop()
{
RECT ClientRect = {'\0'};
GetClientRect(GetFocus(), &ClientRect);
for (int i = 0; i < 0x10000; ++i) {
POINT CaretPos = {'\0'};
GetCaretPos(&CaretPos);
if (ClientRect.top + 10 < CaretPos.y) {
SendMessage(GetFocus(), WM_VSCROLL, SB_LINEDOWN, NULL);
} else {
return Reset(GOTO_HOOK);
}
}
Kdu(VK_UP, VK_DOWN);
return Reset(GOTO_HOOK);
}
int CCommands::OneShotModifierShift()
{
// dummy
ASSERT(0);
static int i = 0;
++i;
return Reset(GOTO_HOOK);
}
int CCommands::OneShotModifierShiftRepeat()
{
// dummy
ASSERT(0);
static int i = 0;
++i;
return Reset(GOTO_HOOK);
}
int CCommands::OneShotModifierCtrl()
{
// dummy
ASSERT(0);
static int i = 0;
++i;
return Reset(GOTO_HOOK);
}
int CCommands::OneShotModifierCtrlRepeat()
{
// dummy
ASSERT(0);
static int i = 0;
++i;
return Reset(GOTO_HOOK);
}
int CCommands::OneShotModifierAlt()
{
// dummy
ASSERT(0);
static int i = 0;
++i;
return Reset(GOTO_HOOK);
}
int CCommands::OneShotModifierAltRepeat()
{
// dummy
ASSERT(0);
static int i = 0;
++i;
return Reset(GOTO_HOOK);
}
int CCommands::CycleItems()
{
ClearNumericArgument();
AdKduAu(VK_ESCAPE);
return Reset(GOTO_HOOK);
}
int CCommands::CycleItemsInversely()
{
ClearNumericArgument();
AdSdKduSuAu(VK_ESCAPE);
return Reset(GOTO_HOOK);
}
// M-t
int CCommands::TransposeWords()
{
static int nStep = 0;
switch (nStep) {
case 0:
nStep = 0;
// CUtils::Log("M-t: 0");
CdKduCu(VK_LEFT);
CaptureClipboardData();
nStep = 1;
return Reset(GOTO_RECURSIVE);
case 1:
nStep = 0;
// CUtils::Log("M-t: 1");
CdSdKduSuCu(VK_RIGHT);
CdKduCu('X');
nStep = 2;
return Reset(GOTO_RECURSIVE);
case 2:
nStep = 0;
// CUtils::Log("M-t: 2");
Su();
CdKduCu(VK_RIGHT);
CdKduCu('V');
Kdu(VK_LEFT);
nStep = 3;
return Reset(GOTO_RECURSIVE);
case 3:
nStep = 0;
// CUtils::Log("M-t: 3");
RestoreClipboardData();
break;
}
return Reset(GOTO_HOOK);
}