dispose is not a member of GDI+ Image class - c++

So I have a program that pulls random images from a folder and creates a collage out of them, and set it to the windows wallpaper. Which seems to work fine. So I thought I would put in a sleep timer and let it automatically update itself without me having to run it every half hour or what ever. I did that and it works great, but I ran into a problem of a memory leak that wasn't noticed before I started looping it. I am attempting to dispose of the GDI+objects, but I keep getting the error that dispose is not a member of GDIplus::Image
I am loading an picture into an Image object, then resizing it and putting it into an array of Images, then I would like to dispose of the first Image. I would then like to dispose of the array after I finish working with the images in it.
This is being done with an old copy of VS2005.
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <string>
#include <iostream>
#include <vector>
#include <dirent.h>
#include <time.h>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include "cwp05rnd.h"
using namespace Gdiplus;
using namespace std;
#pragma comment (lib,"Gdiplus.lib")
#pragma comment (lib, "user32.lib")
int main()
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
HDC hdc;
Graphics graphics(hdc);
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID jpegClsid;
GetEncoderClsid(L"image/jpeg", &jpegClsid);
SetCurrentDirectoryA("E:\\Photos");
ofstream outfile;
outfile.open ("outimgs.txt");
ofstream outfile2;
outfile2.open("imgpos.txt");
srand(time(NULL));
init_genrand(time(NULL));
vector<string> dirlist;
DIR *d;
struct dirent *dir;
int i=0;
d=opendir(".");
if (d)
{
while ((dir=readdir(d)) != NULL)
{
i++;
dirlist.push_back(dir->d_name);
}
closedir(d);
}
Image wp(L"E:\\Dropbox\\Photos\\wallpaper.jpg");
Graphics* wpimage = Graphics::FromImage(&wp);
int r;
int rvsize=100;
int rv[100]={0};
string img;
std::wstring wimg;
const wchar_t* rimg;
double cwidth;
double cheight;
double ratio;
int nheight;
int counter=0;
int full = 0;
int tries = 0;
int hfull = 0;
int imgnum =0;
int last=0;
Image* newpic[10];
while ( tries <10)
{
redo:
tries++;
int newrv=0;
while (newrv ==0)
{
r=genrand_int32()%i;
for (int k=0; k < rvsize; k++)
{
if (rv[k] > 0 && rv[k]==r )
{
break;
}
if (rv[k]==0 && r < i)
{
newrv =1;
rv[k]=r;
last=k;
break;
}
if (rv[k] ==0)
{
break;
}
}
}
img = dirlist[r];
if (img[0]=='.')
{
newrv=0;
goto redo;
}
wimg = std::wstring(img.begin(),img.end());
rimg = wimg.c_str();
Image pic(rimg);
cwidth = pic.GetWidth();
cheight = pic.GetHeight();
if (cheight ==0)
{
outfile2 << "error" << img << endl;
rv[last]=0;
system("pause");
goto redo;
}
ratio = cwidth/cheight;
nheight = nwidth/ratio;
pic.RotateFlip(Rotate180FlipNone);
pic.RotateFlip(Rotate180FlipNone);
newpic[imgnum] = pic.GetThumbnailImage(nwidth,nheight,NULL,NULL);
delete pic[0];
imgnum = imgnum + 1;
}
then there is a long section of flips and rotates on the images in newpic, according to various random values.
wpimage->DrawImage(newpic[k],(j*nwidth),(((k+1)*whitespace)+htot),nwidth,nh[k]);
wp.Save(L"C:\\Temp\\wallpaper\\nwallpaper.jpg", &jpegClsid, NULL);
delete newpic;
setWall();
delete wpimage;
delete wp;
return 0;
}
When I attempt to delete the Image objects, I get an error that says either it can not delete objects that are not pointers, or it cannot convert from GDIplus::Image to void*
Any advice would be appreciated.

I noticed you have Image pic(rimg);
But you are doing delete pic[0];
pic is not a pointer.. not dynamically allocated or something... nor is a array (or maybe it is.. but intuitively I think no..)
* Add *
Oh yeah, if you already solved this, suggests you close the question or at least mention it...

Related

C++ How to remove vertical scrollbar?

I am trying to make a fun program where it display random numbers, but I need to remove the scrollbar so it looks more convincing. I managed to make the program full screen but I can't remove the vertical scrollbar. Screenshot
Code:
#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE, 0);
int output;
bool done = false;
system("color a");
while (!done) {
output = 1 + (rand() % (int)(1000 - 1 + 1));
cout << output;
}
}
There are many ways, one of them is manipulating the size of the internal buffer of the console to have the same size of the window and then using ShowScrollBar function to remove the scrolls.
#include <iostream>
#include <Windows.h>
#include <WinUser.h>
using namespace std;
int main() {
SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE, 0);
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hstdout, &csbi);
csbi.dwSize.X = csbi.dwMaximumWindowSize.X;
csbi.dwSize.Y = csbi.dwMaximumWindowSize.Y;
SetConsoleScreenBufferSize(hstdout, csbi.dwSize);
HWND x = GetConsoleWindow();
ShowScrollBar(x, SB_BOTH, FALSE);
int output;
bool done = false;
system("color a");
while (!done) {
output = 1 + (rand() % (int)(1000 - 1 + 1));
cout << output;
}
}
Another way is to rely on conio.h or another C/C++ header/library which implements user interface functions.

c++ trying to add Peterson algorithm to avoid race condition in shared memory

I have written two program (program 1 and program 2) to communicate with each other using shared memory. program 1 reads from a file a sentence and pass it after modification to get first letter of each word and its size to the next program ( program 2) . I faced race condition problem. I added Peterson algorithm but once I execute the 2 programs one in foreground and one in background I didn't get any result.
-once i remove the Peterson algorithm my programs work
-i'm working in linux using c++
program 1
#include<iostream>
#include<fstream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
int filesize(){
ifstream input;
input.open("file1.txt");
string temp;
int i = 0;
while(input>>temp){i++;}
input.close();
return i;
}
struct shdata
{
char c;
int n;
int size;
bool flag[2];
int turn;
};
int main(){
ifstream input;
input.open("file1.txt");
int shmid;
key_t key = 8006;
struct shdata *shm;
shmid = shmget(key, sizeof(struct shdata), IPC_CREAT | 0666);
if(shmid < 0){
cout<<"Error .. Can not get memory\n";
exit(0);
}
shm = (struct shdata *)shmat (shmid, NULL, 0);
if(shm <= (struct shdata *)(0))
{
cout<<"Errors.. Can not attach\n";
exit(1);
}
shm->flag[0]=false;
shm->flag[1]=true;
string temp;
while(input>>temp){
shm->flag[0]=true;
shm->turn = 1;
while(shm->flag[1]== true && shm-> turn == 1 );
shm->c=temp[0];
shm->n=temp.size();
shm->size = filesize();
shm->flag[0]=false;
sleep(1);
}
return 0;
}
program 2
#include<iostream>
#include<fstream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
int filesize(){
ifstream input;
input.open("file1.txt");
string temp;
int i = 0;
while(input>>temp){i++;}
input.close();
return i;
}
struct shdata
{
char c;
int n;
int size;
bool flag[2];
int turn;
};
int main(){
int shmid;
key_t key = 8006;
struct shdata *shm;
shmid = shmget(key, sizeof(struct shdata), 0);
if(shmid < 0)
{
cout<<"Error .. Can not get memory\n";
exit(0);
}
shm = (struct shdata *)shmat (shmid,0, 0);
if(shm <= (struct shdata *)(0))
{
cout<<"Error .. Can not attach\n";
exit(1);
}
int c =0;
while(c<shm->size){
shm->flag[1] = true;
shm->turn=0;
while( shm->flag[0]==false && shm->turn == 0);
sleep(1);
for(int i = 0; i < shm->n ;i++)
{
cout<<shm->c;
}
cout<<endl;
shm->flag[1]=false;
c++;
}
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
program 2 never gets into the while(c<shm->size) loop because at that point shm->size is 0. To get around it, progran 1 should initialize shm->size before program 2 reaches that point. This might lead to another race condition because there doesn't seem to be any mechanism to ensure that the shared memory is initialized by program 1 before program 2 starts using it.
It seems to work without the Peterson algorithm because in that case program 1 doesn't wait on the flag and initializes shm->size further down in the loop.
You are using the flag member to synchronize you 2 programs but this cant work because you cant suppose the sequence of read/writes. You must use a small dialect in order to make your two programs starts in the correct order.

C++ Background problems

I have a c++ program that generates random files filled with gibberish, but for it to work it needs to run in the background. The method I am using generates a null window. I have made other programs using this background method, but it doesn't work in this program:
#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <fstream>
#include <windows.h>
using namespace std;
string random(int len)
{
string a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
string r;
srand(time(NULL));
for(int i = 0; i < len; i++) r.push_back(a.at(size_t(rand() % 62)));
return r;
}
int main(){
restart:
/*This is the background code*/
HWND window;
AllocConsole();
window - FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(window, 0);
std::string file=random(1);
std::ofstream o(file.c_str());
o << random(999) << std::endl;
goto restart;
return 0;
}
I am using the dev C++ compiler
I just realized my problem, the goto statement needed to not include the null window rendering part, so the window wasn't re-rendered and de-rendered every time. Also there was a - that needed to be an =.

C++ 2Dimensional array

I'm currently learning c++,and the code went so far,until
i made array variables to call a function instead of string,but something went wrong,and i can't figure out what it is.Problem is,it couts correctly only first 2 letters,then it couts the rest as └└└└ symbols.
Here's the code:
#include <iostream>
#include <string>
#include <windows.h>
#include <conio.h>
using namespace std;
int land(){
HANDLE hConsole;
hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN);
char H = 72;
cout<<H;
}
int player(){
HANDLE hConsole;
hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE);
char X = 88;
cout<<X;
}
/*previously,i declared a string inside worldgen,and generated 2d array inside the for loop,but when i changed variables to call a function,first letters were X and H,but then it went └└└└└└└└└└└└└└└└└└└└└└└ for all the remaining characters.What's wrong here? */
int worldgen(int dimX,int dimY,int x,int y){
HANDLE hConsole;
hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
system("TITLE MyTitleText");
int H = land();
int X = player();
string world[dimX][dimY];
for(int c = 0;c<dimY;c++){
for(int count = 0;count<dimX;count++){
world[count][c] = H;
world[x][y] = X;
cout<<world[count][c];
}
cout<<endl;
}
}
int main(){
HANDLE hConsole;
hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
worldgen(70,15,10,10);
cin.get();
}
Neither land() nor player() return anything so neither H nor X are getting any meaningful data are are just garbage data that was uninitialized.
I'm surprised this is even compiling since you have two functions that are supposed to return ints but aren't set to return anything.

Program that returns a list of drive letters

In the example of my computer the desired output should be: "C: E: F: H: N:" . I know it's possible, but what is the simpliest way to do that? Pottering in QueryDosDevice output
#ifndef UNICODE
#define UNICODE
#endif
#include <Windows.h>
#include <fstream>
#include <iostream>
const int REPORT_LENGTH = 5000;
int main(void)
{
TCHAR targetPath[REPORT_LENGTH];
std::ofstream oFile;
oFile.open("dos device query.txt");
QueryDosDevice(NULL,targetPath,REPORT_LENGTH);
for(int i=0; i<REPORT_LENGTH;i++)
if (targetPath[i]=='\0')(targetPath[i]='\n');
for(int i=0; i<REPORT_LENGTH; i++)
oFile<<static_cast<char>(targetPath[i]);
oFile.close();
return 0;
}
would be a huge waste of time and resources. Also function GetLogicalDriveStrings has betrayed me a lot.
#include <Windows.h>
int main()
{
TCHAR buffer[50];
GetLogicalDriveStrings(50,buffer);
MessageBox(0,buffer,"Drives in the system",MB_OK);
return 0;
}
It shows only the "C:\" volumine.
Example with GetLogicalDrives, albeit not with concatenating to a string (which is left as an exercise to the OP and the readers ;)):
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
int __cdecl _tmain(int argc, _TCHAR *argv[])
{
// Get the bit mask of drive letters
DWORD drives = ::GetLogicalDrives();
// Go through all possible letters from a to z
for(int i = 0; i < 26; i++)
{
// Check if the respective bit is set
if(drives & (1 << i))
{
// ... and if so, print it
_tprintf(TEXT("Drive %c: exists\n"), _T('A') + i);
}
}
return 0;
}
GetLogicalDriveStrings() is the way to go, you just have to use to correctly. You are assuming it returns a single string containing all of the drive strings, but that is not true. It returns an array of strings, one for each drive, so you have to loop through the array instead:
#include <windows.h>
int main()
{
TCHAR buffer[(4*26)+1] = {0};
GetLogicalDriveStrings(sizeof(buffer) / sizeof(TCHAR), buffer);
for (LPTSTR lpDrive = buffer; *lpDrive != 0; lpDrive += 4)
MessageBox(NULL, lpDrive, "Drive in the system", MB_OK);
return 0;
}