-
#include problem
I am sure there is a simple fix to this that I am not seeing. I have four files in this project
file : header.h
Code:
#ifndef HEADER_H
#define HEADER_H
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#include "console_message_box.h"
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
void Second();
#endif
file : console_message_box.h
Code:
#ifndef CONSOLE_MESSAGEBOX_H_INCLUDED
#define CONSOLE_MESSAGEBOX_H_INCLUDED
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#include <windows.h>
#include <string>
#include <vector>
#define CMB_ENTER 900001
#define CMB_YESNO 900002
#define CMB_RESPONSE 900003
typedef int RETURNTYPE;
void ConsoleMessageBox(const std::string line,
const RETURNTYPE end)
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD Position, ConsoleSize = GetLargestConsoleWindowSize(hOut);
LPDWORD NumWritten;
std::vector<std::string> vec;
std::vector<std::string>::iterator iter;
std::string::size_type line_length = line.length();
std::string str1, str2;
/* Get Height and Width of the Box */
const int box_length = line_length + 6;
const int box_height = 7;
/* Create the Box */
str1.assign( (box_length - 2), (unsigned char)205);
str2 = (unsigned char)201; str2+= str1; str2+= (unsigned char)187;
vec.push_back(str2);
str1.assign( (box_length - 2), ' ');
str2 = (unsigned char)186; str2+= str1; str2+= (unsigned char)186;
for (int x = 0; x < (box_height - 2); ++x)
vec.push_back(str2);
str1.assign( (box_length - 2), (unsigned char)205);
str2 = (unsigned char)200; str2+= str1; str2+= (unsigned char)188;
vec.push_back(str2);
/* Set Box coord's to the center of the screen */
Position.X = ( (ConsoleSize.X - box_length) / 2);
Position.Y = ( (ConsoleSize.Y - box_height) / 2) + 1;
/* Set the Color of the Box */
SetConsoleTextAttribute(hOut, FOREGROUND_RED |
FOREGROUND_INTENSITY);
/* Display the Box */
for (iter = vec.begin(); iter != vec.end(); ++iter) {
str1 = *iter;
SetConsoleCursorPosition(hOut, Position);
WriteConsole(hOut, str1.c_str(), str1.length(), NumWritten, NULL);
++Position.Y;
}
Position.Y = ( (ConsoleSize.Y - 2) / 2);
if (!line.empty() ) {
Position.X = ( (ConsoleSize.X - line.length() ) / 2);
SetConsoleCursorPosition(hOut, Position);
WriteConsole(hOut, line.c_str(), line.length(), NumWritten, NULL);
}
if (end == CMB_ENTER) str1 = "<enter>";
else if (end == CMB_YESNO) str1 = "( y / n ) ";
else if (end == CMB_RESPONSE) str1 = ">>";
Position.Y += 2;
Position.X = ( (ConsoleSize.X - str1.length() ) / 2);
SetConsoleCursorPosition(hOut, Position);
WriteConsole(hOut, str1.c_str(), str1.length(), NumWritten, NULL);
/* Set Colors back to normal */
SetConsoleTextAttribute(hOut, FOREGROUND_BLUE |
FOREGROUND_GREEN |
FOREGROUND_RED);
return;
}
#endif
file : main.cpp
Code:
#include "header.h"
int main() {
// Make console window full screen
SetConsoleTitle("Test");
HWND hWnd = FindWindow(NULL, "Test");
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD ConsoleSize = GetLargestConsoleWindowSize(hOut);
SMALL_RECT DisplayArea = {0, 0, 0, 0};
SetConsoleScreenBufferSize(hOut, ConsoleSize);
DisplayArea.Right = ConsoleSize.X - 1;
DisplayArea.Bottom = ConsoleSize.Y - 1;
SetConsoleWindowInfo(hOut, TRUE, &DisplayArea);
ShowWindow(hWnd, SW_MAXIMIZE);
std::cout<<"Enter a line to be displayed : ";
std::string line;
getline(std::cin, line);
ConsoleMessageBox(line, CMB_ENTER);
std::cin.clear();
std::cin.get();
Second();
std::cin.clear();
std::cin.get();
return 0;
}
file : next.cpp
Code:
#include "header.h"
void Second() {
system("cls");
std::cout<<"Enter another line : ";
std::string line2;
getline(std::cin, line2);
ConsoleMessageBox(line2, CMB_ENTER);
return;
}
I am getting an error "multiple definition of `ConsoleMessageBox(std::string, int)' ". When I do away with the next.cpp file and put its contents at the end of the main.cpp file then it compiles and runs fine. I thought that using the #ifndef/#endif would prevent these kind of problems?
-
No. You have to put the code of ConsoleMessageBox in its own source file.
The #ifdef is only for preventing multiple definitions of things that may appear more than once across compilation units, such as class definitions, typedefs, macros, ...
Things that may only appear once even across compilation units (such as function definitions) should not be put into header files in the first place.
A compilation unit, btw, is a .cpp and all the code it #includes.
-
My intent here is to create a file (ConsoleMessageBox) that can be placed into the include directory for my compiler, so that when I write other programs I can just #include<ConsoleMessageBox> to use it insted ov having to add it to ecery project that I create. Forgive me for being dense but if I have to put the definition in a separate .cpp than the .h how do I go about doing the #include? That would make (for the example above) a .h and 2 .cpp for the program and a .h and a .cpp for the ConsoleMessageBox?
I have been looking around but have not found much help on this, if anyone perhaps knows of a tutorial on this subject it i am sure it would help me out a lot.
-
You could make the function inline and leave it in the header then just #include the header in the files that want to use the function.
Otherwise, if you define the function in the source file you'd have to add that source file to any projects that want to use that function, or compile it into a library and link with that library.
-
Visual C++ has a pragma for autolinking. Thus, you could compile the code into a library, put it in your compiler's library search path, and put this line into the header:
Code:
#pragma comment (lib, "whatever.lib")