如何解決最小化时一下就没了

thomasgtr34 2008-11-14 03:06:19
一行只可輸入20字元,第21個回車去下一行,第20個字元發出"叮"一聲
顯示字元位置

但解決不了輸入字元後,把視窗最小化,回復時要顯示上次輸入的字元,當最小化時一下就沒了
使用過WM_PAINT,但不停Loop,可能是用錯了
是否要用BeginPaint
初學WIN32 API 菜烏
請指教

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
char szWinName[] = "MyWin"; // name of window class
char outStr[255] = ""; // holds output string

int curX = 1; //****************defind posts to the left top corner
int curY = 1; //****************
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInstance, LPSTR IpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;

wcl.cbSize = sizeof(wcl);
wcl.hInstance = hThisInst; // handle to this instance
wcl.lpszClassName = szWinName; // window class name
wcl.lpfnWndProc = WindowFunc; // name of the window callback function
wcl.style = 0; // default window style
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon
wcl.hIconSm = NULL; // use small version of large icon
wcl.hCursor = LoadCursor(NULL, IDC_ARROW); // cursor style
wcl.lpszMenuName = NULL; // no class menu
wcl.cbClsExtra = 0; // no extra memory needed
wcl.cbWndExtra = 0; // no extra memory needed
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

if(!RegisterClassEx(&wcl))
return 0; // exit if failed to register the window

hwnd = CreateWindow(szWinName,"EX",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL, NULL, hThisInst,NULL);


ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg); // translate keyboard messages
DispatchMessage(&msg); // return control to Windows 2000
};

return msg.wParam;
}

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam)
{
HDC hdc;

switch(message)
{


case WM_CHAR: // process keystroke

hdc = GetDC(hwnd);
sprintf(outStr, "%c", (char) wParam);
TextOut(hdc, curX, curY, outStr, strlen(outStr)); // output char


sprintf(outStr, "%c", (char) wParam); //clean output
TextOut(hdc, 460, 410, " ", 10); //clean output

sprintf(outStr, "The cursor position (x, y) at %d, %d", curX, curY); //output cursor position
TextOut(hdc, 250, 410, outStr, strlen(outStr)); //output cursor position

if(curY>400) //
{
break;
}
else if(curX<190) // set the line only have 20 characters
{
curX +=10;
}
else
{
curY +=20; //when the line over 20 characters
curX = 0; //it have pass the new line
PlaySound ("DING.wav", NULL, SND_FILENAME | SND_ASYNC) ;
}
ReleaseDC(hwnd, hdc); // release device context
break;

case WM_DESTROY: // terminate the program
PostQuitMessage(0);
break;


default:

return DefWindowProc(hwnd, message, wParam, lParam);

}
return 0;
}
...全文
417 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lsldd 2008-11-15
  • 打赏
  • 举报
回复
不知道你认真看了我7楼的代码没有。。。
自己拷贝过去编译一下看效果
lsldd 2008-11-15
  • 打赏
  • 举报
回复
不知道你认真看了我7楼的代码没有。。。
自己拷贝过去看效果
thomasgtr34 2008-11-14
  • 打赏
  • 举报
回复
寫不出來了...


#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
char szWinName[] = "MyWin"; // name of window class
char outStr[255] = ""; // holds output string
char savechar[65525];
int savect= 0;

int curX = 1; //****************defind posts to the left top corner
int curY = 1; //****************
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInstance, LPSTR IpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;

wcl.cbSize = sizeof(wcl);
wcl.hInstance = hThisInst; // handle to this instance
wcl.lpszClassName = szWinName; // window class name
wcl.lpfnWndProc = WindowFunc; // name of the window callback function
wcl.style = 0; // default window style
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon
wcl.hIconSm = NULL; // use small version of large icon
wcl.hCursor = LoadCursor(NULL, IDC_ARROW); // cursor style
wcl.lpszMenuName = NULL; // no class menu
wcl.cbClsExtra = 0; // no extra memory needed
wcl.cbWndExtra = 0; // no extra memory needed
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

if(!RegisterClassEx(&wcl))
return 0; // exit if failed to register the window

hwnd = CreateWindow(szWinName,"LAB 3",WS_OVERLAPPEDWINDOW | WS_HSCROLL,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL, NULL, hThisInst,NULL);

ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg); // translate keyboard messages
DispatchMessage(&msg); // return control to Windows 2000
};

return msg.wParam;
}

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam)
{
HDC hdc;
int i;
switch(message)
{


case WM_CHAR: // process keystroke

hdc = GetDC(hwnd);
savechar[savect]=(char) wParam;
savect++;
sprintf(outStr, "%c", (char) wParam);
TextOut(hdc, curX, curY, outStr, strlen(outStr)); // output char


sprintf(outStr, "%c", (char) wParam); //clean output
TextOut(hdc, 460, 410, " ", 10); //clean output

sprintf(outStr, "The cursor position (x, y) at %d, %d", curX, curY); //output cursor position
TextOut(hdc, 250, 410, outStr, strlen(outStr)); //output cursor position

if(curY>400) //
{
break;
}
else if(curX<190) // set the line only have 20 characters
{
curX +=10;
}
else
{
curY +=20; //when the line over 20 characters
curX = 0; //it have pass the new line
PlaySound ("DING.wav", NULL, SND_FILENAME | SND_ASYNC) ;
}
ReleaseDC(hwnd, hdc); // release device context

break;
case WM_PAINT:
for(i=0; i<strlen(savechar);i++)
{
TextOut(hdc,charX[],charY[],savechar[i],strlen(savechar);
}
case WM_DESTROY: // terminate the program
PostQuitMessage(0);
break;


default:
/* Let Windows 2000 process any messages not specified in
the preceding switch statement. */
return DefWindowProc(hwnd, message, wParam, lParam);
EndPaint(hwnd,hdc);
}
return 0;
}
xxgamexx 2008-11-14
  • 打赏
  • 举报
回复
顶起


拖动窗体,最小化等操作 好象都会重新刷新一次窗体,所以如果你不保存当前窗体的字符,在下次刷新前就会清除。


所以用个数组存储输入的字符,在WM_PAINT 动作里再把存储的字符显示到窗体上,这样字符就不会丢失了。

不知道明白没 很就没弄SDK了
lsldd 2008-11-14
  • 打赏
  • 举报
回复
帮你简单的修改了一下,你可以参考:
#include <windows.h> 
#include <stdio.h>
struct charInfo{
int x, y;
char ch;
};// 这个结构体用来保存每个char的信息
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
char szWinName[] = "MyWin"; // name of window class
char outStr[255] = ""; // holds output string
charInfo chInfo[65525]; // 保存char的结构数组
int currentChar = 0; // 记录当前总字符数
int curX = 1; //****************defind posts to the left top corner
int curY = 1; //****************
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInstance, LPSTR IpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;
wcl.cbSize = sizeof(wcl);
wcl.hInstance = hThisInst; // handle to this instance
wcl.lpszClassName = szWinName; // window class name
wcl.lpfnWndProc = WindowFunc; // name of the window callback function
wcl.style = 0; // default window style
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon
wcl.hIconSm = NULL; // use small version of large icon
wcl.hCursor = LoadCursor(NULL, IDC_ARROW); // cursor style
wcl.lpszMenuName = NULL; // no class menu
wcl.cbClsExtra = 0; // no extra memory needed
wcl.cbWndExtra = 0; // no extra memory needed
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

if(!RegisterClassEx(&wcl))
return 0; // exit if failed to register the window

hwnd = CreateWindow(szWinName,"EX",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL, NULL, hThisInst,NULL);


ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg); // translate keyboard messages
DispatchMessage(&msg); // return control to Windows 2000
};
return msg.wParam;
}

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
int i;
switch(message)
{
case WM_PAINT:// 处理PAINT消息
hdc = BeginPaint(hwnd, &ps);
// TODO: Add any drawing code here...
TextOut(hdc, 250, 410, outStr, strlen(outStr)); //output cursor position
for ( i = 0; i < currentChar; i++)// 顺序画出之前所有char
{
sprintf(outStr, "%c", chInfo[i].ch); //clean output
TextOut(hdc, chInfo[i].x, chInfo[i].y, outStr, 1); // output char
}
EndPaint(hwnd, &ps);
break;

case WM_CHAR: // process keystroke
// 在这里保存下每个char的信息到数组里
hdc = GetDC(hwnd);
sprintf(outStr, "%c", (char) wParam);
chInfo[currentChar].x = curX;
chInfo[currentChar].y = curY;
chInfo[currentChar].ch = (char) wParam;
currentChar++;

TextOut(hdc, curX, curY, outStr, strlen(outStr)); // output char


sprintf(outStr, "%c", (char) wParam); //clean output
TextOut(hdc, 460, 410, " ", 10); //clean output

sprintf(outStr, "The cursor position (x, y) at %d, %d", curX, curY); //output cursor position
TextOut(hdc, 250, 410, outStr, strlen(outStr)); //output cursor position

if(curY>400) //
{
break;
}
else if(curX <190) // set the line only have 20 characters
{
curX +=10;
}
else
{
curY +=20; //when the line over 20 characters
curX = 0; //it have pass the new line
//PlaySound ("DING.wav", NULL, SND_FILENAME | SND_ASYNC) ;
}
ReleaseDC(hwnd, hdc); // release device context
break;

case WM_DESTROY: // terminate the program
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
qq675927952 2008-11-14
  • 打赏
  • 举报
回复
up 虽然看不懂
thomasgtr34 2008-11-14
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wudeshou82666 的回复:]
关注
水平有限,看不懂楼主描叙的效果
[/Quote]
小弟表達能力差,這是題目

1. It can display more than one character that entered by the user in the same line.
2. Each character entered will be echoed to the screen of the window.
3. Each line can only display 20 characters.
4. If more than 20 characters are typed, it wraps to the next line.
5. The window can display ONLY 20 lines.
6. At the end of each line, a selected “.wav” sound file should be played. Then the current
cursor position should shift to the next line. Typing will begin on next line.
7. Location of current cursor position (x, y) should be shown on the screen.
8. The WM_PAINT message MUST be used, so that what you typed on the screen can be
retained upon window restore.
9. When more than 20 lines are typed, the screen should scroll up accordingly.
lsldd 2008-11-14
  • 打赏
  • 举报
回复
你的处理逻辑有问题
每次窗口最小化再恢复,OnPaint都会调用一次。
而这个时候,你先前所绘制的字符都不可恢复了
所以你要做的设立一个数据结构,保存绘制的每个字符
然后在OnPaint函数里绘制先前所有字符
Zark 2008-11-14
  • 打赏
  • 举报
回复
在WM_PAINT中计算字符串的显示位置.
thomasgtr34 2008-11-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 Zark 的回复:]
在WM_CHAR处理生成字符串,然后在WM_PAINT中画字符串就行了.
[/Quote]
不太明白,請問可以做出來參考嗎?
wudeshou82666 2008-11-14
  • 打赏
  • 举报
回复
关注
水平有限,看不懂楼主描叙的效果
zjf30366 2008-11-14
  • 打赏
  • 举报
回复
关注。
  • 打赏
  • 举报
回复
不敢说话,学习
thomasgtr34 2008-11-14
  • 打赏
  • 举报
回复
輸入的字元已解決,但顯示字元位置的字句依然會失掉......


#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
char szWinName[] = "MyWin"; // name of window class
char outStr[255] = ""; // holds output string
char savechar[6325]="";
char pac[6325];
char locat[255] = "The cursor position (x, y) at ";
int savect= 0;
int xx[6325] ;
int yy[6325] ;
int a = 0;
int c = 0;
int curX = 1; //****************defind posts to the left top corner
int curY = 1; //****************
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInstance, LPSTR IpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;

wcl.cbSize = sizeof(wcl);
wcl.hInstance = hThisInst; // handle to this instance
wcl.lpszClassName = szWinName; // window class name
wcl.lpfnWndProc = WindowFunc; // name of the window callback function
wcl.style = 0; // default window style
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon
wcl.hIconSm = NULL; // use small version of large icon
wcl.hCursor = LoadCursor(NULL, IDC_ARROW); // cursor style
wcl.lpszMenuName = NULL; // no class menu
wcl.cbClsExtra = 0; // no extra memory needed
wcl.cbWndExtra = 0; // no extra memory needed
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

if(!RegisterClassEx(&wcl))
return 0; // exit if failed to register the window

hwnd = CreateWindow(szWinName,"LAB 3",WS_OVERLAPPEDWINDOW | WS_HSCROLL,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL, NULL, hThisInst,NULL);

ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg); // translate keyboard messages
DispatchMessage(&msg); // return control to Windows 2000
};

return msg.wParam;
}

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT paintstruct;
int i = 0;

switch(message)
{


case WM_CHAR: // process keystroke

hdc = GetDC(hwnd);


sprintf(outStr, "%c", (char) wParam);
savechar[savect]=(char) wParam;
savect = savect + 1;
TextOut(hdc, curX, curY, outStr, strlen(outStr)); // output char



//locat[31]="The cursor position (x, y) at "; // , curX, curY; //output cursor position
TextOut(hdc, 250, 410, locat, strlen(locat)); //output cursor position

if(curY>400) //
{
break;
}
else

if(curX<190) // set the line only have 20 characters
{

xx[a]=curX;
yy[a]=curY;
curX +=10;
a=a+1;

}
else
{
xx[a]=curX;
yy[a]=curY;
a=a+1;

curY +=20; //when the line over 20 characters
curX = 0; //it have pass the new line
PlaySound ("DING.wav", NULL, SND_FILENAME | SND_ASYNC) ;
}



ReleaseDC(hwnd, hdc); // release device context

break;

case WM_PAINT:
hdc = BeginPaint (hwnd, &paintstruct);
for(i=0; i<a;i++)
{
pac[0]=savechar[i];
TextOut(hdc,xx[c],yy[c],pac,1);
c++;
}
c = 0;
EndPaint(hwnd, &paintstruct);
break;

case WM_DESTROY: // terminate the program
PostQuitMessage(0);
break;


default:
/* Let Windows 2000 process any messages not specified in
the preceding switch statement. */
return DefWindowProc(hwnd, message, wParam, lParam);

}
return 0;
}
Zark 2008-11-14
  • 打赏
  • 举报
回复
在WM_CHAR处理生成字符串,然后在WM_PAINT中画字符串就行了.
wudeshou82666 2008-11-14
  • 打赏
  • 举报
回复
UP
7楼
效果差不多就是你要的了

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧