老师未批改
作业
完成如下程序题#include <windows.h>
#define WINMAXIMUM 100
HWND g_hwnds[WINMAXIMUM] = { 0 };
int g_winnum = 0;
BOOL CALLBACK EnumWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam)
{
char classname[MAXBYTE] = { 0 };
GetClassNameA(hwnd, classname, MAXBYTE);
if (strcmp("TXGuiFoundation", classname) == 0)
{
g_hwnds[g_winnum] = hwnd;
g_winnum++;
}
return TRUE;
}
int main()
{
EnumWindows(EnumWindowsProc, NULL);
//每排3个窗口分4列排列
//让所有窗口依次从左向右飞过
//让所有窗口依次挨个从左向右飞过
//让窗口排列成
//*
//**
//***
//**
//*
//让窗口排列成
// *
// **
// ***
// **
// *
//让窗口分3行,每次每行飞入一个
//模拟窗口反弹
//将数组中奇数下标的窗口从下往上飞,偶数下标的窗口从上往下飞。每次都需要反弹效果
return 0;
}作答
程序代码如下:#include <stdio.h>
#include <windows.h>
#include <shellapi.h>
#include <conio.h>
#define WINMAXIMUM 100
#define WINDOW_HEIGHT 180 // 窗口高度
#define WINDOW_WIDTH 300 // 窗口宽度
#define BORDER_PADDING 20 // 距离边界的长度
#define OUTPUT_LINE_MID 3 // 输出三角形的中间行数
#define MOVE_SPEED 10 // 窗口移动速度
HWND g_hwnds[WINMAXIMUM] = { 0 };
int g_winnum = 0;
RECT g_rect; // 定义保存第一个启动的程序的大小, 在最后还原使用.
BOOL CALLBACK EnumWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam)
{
char classname[MAXBYTE] = { 0 };
GetClassNameA(hwnd, classname, MAXBYTE);
// if (strcmp("TXGuiFoundation", classname) == 0)
if (strcmp("Notepad", classname) == 0)
{
g_hwnds[g_winnum] = hwnd;
g_winnum++;
}
return TRUE;
}
BOOL MoveWindowSelf(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint)
{
// 让窗口前置
SetForegroundWindow(hWnd);
// 移动窗口
return MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint);
}
/************************************************************************/
/* 移动窗口, 从上至下 */
/************************************************************************/
int MoveWindowTopToBottom(int iScHeight, int i)
{
int iJumpTimes = 1;
// 计算窗口的left位置
int iLeft = BORDER_PADDING;
int iTop = BORDER_PADDING;
_Bool bBottom = FALSE;
int iMaxHeight = iScHeight - BORDER_PADDING - WINDOW_HEIGHT;
while (bBottom ? iTop > iMaxHeight : iTop < iMaxHeight)
{
MoveWindowSelf(g_hwnds[i], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
// 控制右移
iLeft += 4;
// 控制上移还是下移
// 在到达底部之后需要上移, 在到达上边最高处后需要下移.
if (bBottom)
{
iTop -= MOVE_SPEED;
}
else
{
iTop += MOVE_SPEED;
}
// 设置是否到达底部, 并设置此时的最高点
if (!bBottom && iTop > iMaxHeight)
{
bBottom = TRUE;
iMaxHeight = iScHeight - BORDER_PADDING - WINDOW_HEIGHT - iMaxHeight / (2 * iJumpTimes++);
}
// 判断是否到达最高点, 并还原最高点
if (bBottom && iTop < iMaxHeight)
{
bBottom = FALSE;
iMaxHeight = iScHeight - BORDER_PADDING - WINDOW_HEIGHT;
}
// 不能在弹了
if (iMaxHeight < MOVE_SPEED) break;
Sleep(10);
}
return 0;
}
/************************************************************************/
/* 移动窗口, 从下至上 */
/************************************************************************/
int MoveWindowBottomToTop(int iScWidth, int iScHeight, int i)
{
int iJumpTimes = 1;
// 计算窗口的left位置
int iLeft = iScWidth - BORDER_PADDING - WINDOW_WIDTH;
int iTop = iScHeight - BORDER_PADDING - WINDOW_HEIGHT;
_Bool bTop = FALSE;
int iMaxHeight = BORDER_PADDING;
while (bTop ? iTop <= iMaxHeight : iTop >= iMaxHeight)
{
MoveWindowSelf(g_hwnds[i], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
// 控制左移
iLeft -= 3;
// 控制上移还是下移
// 在到达顶部之后需要下移, 在到达下边最高处后需要上移.
if (bTop)
{
iTop += MOVE_SPEED;
}
else
{
iTop -= MOVE_SPEED;
}
// 设置是否到达顶部, 并设置此时的最高点
if (!bTop && iTop < iMaxHeight)
{
bTop = TRUE;
iMaxHeight = iScHeight / (2 * iJumpTimes++);
}
// 判断是否到达最高点, 并还原顶部
if (bTop && iTop > iMaxHeight)
{
bTop = FALSE;
iMaxHeight = BORDER_PADDING;
}
// 不能在弹了
// if (iMaxHeight < MOVE_SPEED) break;
Sleep(10);
}
return 0;
}
int main()
{
//////////////////////////////////////////////////////////////////////////
// 运行前的准备
printf("运行前准备开始!\n");
for (int i = 0; i < 12; i++)
{
ShellExecuteA(NULL, "open", "C:\\Windows\\System32\\notepad.exe", NULL, NULL, SW_SHOWNORMAL);
}
// 暂停2秒 防止运行缓慢不能获取到全部的窗口
Sleep(2000);
printf("运行前准备完成!\n");
//////////////////////////////////////////////////////////////////////////
EnumWindows(EnumWindowsProc, NULL);
//////////////////////////////////////////////////////////////////////////
// 公共用途
printf("共找到窗口[%d]个!", g_winnum);
// 获取屏幕分辨率
int iScWidth = GetSystemMetrics(SM_CXSCREEN);
int iScHeight = GetSystemMetrics(SM_CYSCREEN);
// 设置窗口大小和窗口标题
for (int i = 0; i < g_winnum; i++)
{
if (i == 0)
{
// 保存原始窗口大小, 做还原使用
GetWindowRect(g_hwnds[i], &g_rect);
}
SetWindowPos(g_hwnds[i], NULL, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, SWP_NOMOVE);
char strWindowTitle[20] = { '\0' };
sprintf_s(strWindowTitle, 20, "花心胡萝卜 & %d", i);
// 设置窗口标题
SetWindowTextA(g_hwnds[i], strWindowTitle);
}
// 计算窗口的横向间隔
int iLeftLen = (iScWidth - 2 * BORDER_PADDING) / 3;
// 计算窗口的纵向间隔
int iTopLen = (iScHeight - 2 * BORDER_PADDING) / 4;
//////////////////////////////////////////////////////////////////////////
printf("按下任意键进行窗口4行3列排列!\n");
_getch();
/////////////////////////////////////////////////////////////////////////
// 每排4个窗口分3列排列;
// 开始进行排列
printf("开始进行排列, 每排4个窗口, 一共3排.\n");
for (int i = 0; i < g_winnum; i++)
{
// 计算窗口的left位置
int iLeft = BORDER_PADDING + iLeftLen * (i % 3);
int iTop = BORDER_PADDING + iTopLen * (i % 4);
MoveWindowSelf(g_hwnds[i], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
Sleep(100);
}
//////////////////////////////////////////////////////////////////////////
printf("按下任意键进开始让所有窗口依次从左向右飞过!\n");
_getch();
//////////////////////////////////////////////////////////////////////////
//让所有窗口依次从左向右飞过
printf("开始让所有窗口依次从左向右飞过!\n");
for (int i = 0; i < g_winnum; i++)
{
// 计算窗口的left位置
int iLeft = BORDER_PADDING;
int iTop = BORDER_PADDING;
MoveWindowSelf(g_hwnds[i], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
while (iLeft < iScWidth - 2 * BORDER_PADDING - WINDOW_WIDTH)
{
MoveWindowSelf(g_hwnds[i], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
iLeft += MOVE_SPEED;
Sleep(10);
}
}
//////////////////////////////////////////////////////////////////////////
printf("按下任意键进开始让所有窗口依次从右向左飞过!\n");
_getch();
//////////////////////////////////////////////////////////////////////////
//让所有窗口依次挨个从左向右飞过
printf("开始让所有窗口依次从左向右飞过!\n接下来开始列队~");
for (int i = g_winnum - 1; i >= 0; i--)
{
MoveWindowSelf(g_hwnds[i], 0 - WINDOW_WIDTH, BORDER_PADDING, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
}
printf("列队完成!开始飞入~~~\n");
// 计算窗口的left位置
int iLeft = 0 - WINDOW_WIDTH;
int iTop = BORDER_PADDING;
while (iLeft < iScWidth - BORDER_PADDING - WINDOW_WIDTH)
{
for (int i = 0; i < g_winnum; i++)
{
// 这里不再进行窗口焦点前置, 因为会盖住前边的窗口很不好看
MoveWindow(g_hwnds[i], iLeft - BORDER_PADDING * i, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
}
iLeft += MOVE_SPEED;
//Sleep(10);
}
//////////////////////////////////////////////////////////////////////////
printf("按下任意键进开始让窗口排列为以下形状:\n");
printf("*\n");
printf("**\n");
printf("***\n");
printf("**\n");
printf("*\n");
_getch();
//////////////////////////////////////////////////////////////////////////
//让窗口排列成
//*
//**
//***
//**
//*
printf("开始让窗口排列为以下形状:\n");
printf("*\n");
printf("**\n");
printf("***\n");
printf("**\n");
printf("*\n");
int iIndex = 0;
int iLineNumReal = 0;
_Bool bMid = FALSE;
for (int iLineNum = 0; iLineNum < OUTPUT_LINE_MID; bMid ? iLineNum-- : iLineNum++, iLineNumReal++)
{
if (iIndex + 1 > g_winnum) break;
if (iLineNum < 0) break;
if (iLineNumReal == OUTPUT_LINE_MID - 1) bMid = TRUE;
for (int iColNum = 0; iColNum < iLineNum + 1; iColNum++)
{
// 计算窗口的left位置
int iLeft = BORDER_PADDING + iLeftLen * iColNum;
int iTop = BORDER_PADDING + iTopLen * iLineNumReal;
if (iIndex + 1 > g_winnum) break;
MoveWindowSelf(g_hwnds[iIndex++], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
Sleep(100);
}
}
printf("隐藏多余的窗口!\n");
for (int i = iIndex; i < g_winnum; i++)
{
ShowWindow(g_hwnds[i], SW_HIDE);
}
//////////////////////////////////////////////////////////////////////////
printf("按下任意键进开始让窗口排列为以下形状:\n");
printf(" *\n");
printf(" **\n");
printf(" ***\n");
printf(" **\n");
printf(" *\n");
_getch();
//////////////////////////////////////////////////////////////////////////
//让窗口排列成
// *
// **
// ***
// **
// *
for (int i = iIndex; i < g_winnum; i++)
{
ShowWindow(g_hwnds[i], SW_SHOWNORMAL);
}
printf("开始让窗口排列为以下形状:\n");
printf(" *\n");
printf(" **\n");
printf(" ***\n");
printf(" **\n");
printf(" *\n");
iIndex = 0;
iLineNumReal = 0;
bMid = FALSE;
for (int iLineNum = 0; iLineNum < OUTPUT_LINE_MID; bMid ? iLineNum-- : iLineNum++, iLineNumReal++)
{
if (iIndex + 1 > g_winnum) break;
if (iLineNum < 0) break;
if (iLineNumReal == OUTPUT_LINE_MID - 1) bMid = TRUE;
for (int iColNum = 0; iColNum < iLineNum + 1; iColNum++)
{
// 计算窗口的left位置
int iLeft = iScWidth - (BORDER_PADDING + WINDOW_WIDTH) * (iColNum + 1);
int iTop = BORDER_PADDING + iTopLen * iLineNumReal;
if (iIndex + 1 > g_winnum) break;
MoveWindowSelf(g_hwnds[iIndex++], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
Sleep(100);
}
}
printf("隐藏多余的窗口!\n");
for (int i = iIndex; i < g_winnum; i++)
{
ShowWindow(g_hwnds[i], SW_HIDE);
}
//////////////////////////////////////////////////////////////////////////
printf("按下任意键开始让窗口分为3行, 每次飞入一个!\n");
_getch();
//////////////////////////////////////////////////////////////////////////
//让窗口分3行,每次每行飞入一个
for (int i = iIndex; i < g_winnum; i++)
{
ShowWindow(g_hwnds[i], SW_SHOWNORMAL);
}
printf("开始让窗口分为3行, 每次飞入一个!\n");
for (int i = 0; i < g_winnum; i++)
{
// 计算窗口的left位置
int iLeft = 0 - WINDOW_WIDTH;
int iTop = BORDER_PADDING + iTopLen * (i / 4);
MoveWindowSelf(g_hwnds[i], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
while (iLeft < BORDER_PADDING * (i % 4 + 1) + WINDOW_WIDTH * (i % 4))
{
MoveWindowSelf(g_hwnds[i], iLeft, iTop, WINDOW_WIDTH, WINDOW_HEIGHT, TRUE);
iLeft += MOVE_SPEED;
Sleep(10);
}
}
//////////////////////////////////////////////////////////////////////////
printf("按下任意键模拟窗口反弹!\n");
_getch();
//////////////////////////////////////////////////////////////////////////
//模拟窗口反弹
printf("模拟窗口反弹!\n");
printf("所有窗口初始位置!\n");
for (int i = 0; i < g_winnum; i++)
{
SetWindowPos(g_hwnds[i], NULL, BORDER_PADDING, BORDER_PADDING, 0, 0, SWP_NOSIZE);
}
for (int i = 0; i < g_winnum; i++)
{
MoveWindowTopToBottom(iScHeight, i);
}
//////////////////////////////////////////////////////////////////////////
printf("按下任意键将数组中奇数下标的窗口从下往上飞,偶数下标的窗口从上往下飞。每次都需要反弹效果!\n");
_getch();
//////////////////////////////////////////////////////////////////////////
//将数组中奇数下标的窗口从下往上飞,偶数下标的窗口从上往下飞。每次都需要反弹效果
printf("将数组中奇数下标的窗口从下往上飞,偶数下标的窗口从上往下飞。每次都需要反弹效果!\n");
printf("所有窗口初始位置!\n");
for (int i = 0; i < g_winnum; i++)
{
if (i % 2 == 0)
{
SetWindowPos(g_hwnds[i], NULL, BORDER_PADDING, BORDER_PADDING, 0, 0, SWP_NOSIZE);
}
else
{
SetWindowPos(g_hwnds[i], NULL, iScWidth - BORDER_PADDING - WINDOW_WIDTH, iScHeight - BORDER_PADDING - WINDOW_HEIGHT, 0, 0, SWP_NOSIZE);
}
}
for (int i = 0; i < g_winnum; i++)
{
if (i % 2 == 0)
{
MoveWindowTopToBottom(iScHeight, i);
}
else
{
MoveWindowBottomToTop(iScWidth, iScHeight, i);
}
}
//////////////////////////////////////////////////////////////////////////
printf("按下任意键退出程序!\n");
_getch();
//////////////////////////////////////////////////////////////////////////
// 清理工作
for (int i = 0; i < g_winnum; i++)
{
// DWORD pidWindow;
// 通过窗口句柄找到进程pid
// GetWindowThreadProcessId(g_hwnds[i], &pidWindow);
// 还原原始位置和大小
SetWindowPos(g_hwnds[i], NULL, g_rect.left, g_rect.top,
g_rect.right - g_rect.left, g_rect.bottom - g_rect.top, SWP_SHOWWINDOW);
PostMessage(g_hwnds[i], WM_CLOSE, 0, 0);
}
//////////////////////////////////////////////////////////////////////////
return 0;
}运行效果(运行效果是动态图, 67+MB, 如不能观看, 可右键点击我选择另存为后观看):
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2016-10-06 at 03:16 pm
